// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as Common from '../../core/common/common.js';
import * as Host from '../../core/host/host.js';
import * as i18n from '../../core/i18n/i18n.js';
import * as Platform from '../../core/platform/platform.js';
import * as TextUtils from '../text_utils/text_utils.js';

import {Events, type IsolatedFileSystemManager} from './IsolatedFileSystemManager.js';
import {Events as PlatformFileSystemEvents, PlatformFileSystem, PlatformFileSystemType} from './PlatformFileSystem.js';

const UIStrings = {
  /**
   * @description Text in Isolated File System of the Workspace settings in Settings
   * @example {folder does not exist} PH1
   */
  fileSystemErrorS: 'File system error: {PH1}',
  /**
   * @description Error message when reading a remote blob
   */
  blobCouldNotBeLoaded: 'Blob could not be loaded.',
  /**
   * @description Error message when reading a file.
   * @example {c:\dir\file.js} PH1
   * @example {Underlying error} PH2
   */
  cantReadFileSS: 'Can\'t read file: {PH1}: {PH2}',
  /**
   * @description Text to show something is linked to another
   * @example {example.url} PH1
   */
  linkedToS: 'Linked to {PH1}',
  /**
   * @description Error message shown when devtools failed to create a file system directory.
   * @example {path/} PH1
   */
  createDirFailedBecausePathIsFile:
      'Overrides: Failed to create directory {PH1} because the path exists and is a file.',
  /**
   * @description Error message shown when devtools failed to create a file system directory.
   * @example {path/} PH1
   */
  createDirFailed: 'Overrides: Failed to create directory {PH1}. Are the workspace or overrides configured correctly?'
} as const;
const str_ = i18n.i18n.registerUIStrings('models/persistence/IsolatedFileSystem.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
export class IsolatedFileSystem extends PlatformFileSystem {
  private readonly manager: IsolatedFileSystemManager;
  readonly #embedderPath: Platform.DevToolsPath.RawPathString;
  private readonly domFileSystem: FileSystem;
  private readonly excludedFoldersSetting:
      Common.Settings.Setting<Record<Platform.DevToolsPath.UrlString, Platform.DevToolsPath.EncodedPathString[]>>;
  #excludedFolders: Set<Platform.DevToolsPath.EncodedPathString>;
  private readonly excludedEmbedderFolders: Platform.DevToolsPath.RawPathString[] = [];
  readonly #initialFilePaths = new Set<Platform.DevToolsPath.EncodedPathString>();
  readonly #initialGitFolders = new Set<Platform.DevToolsPath.EncodedPathString>();
  private readonly fileLocks = new Map<Platform.DevToolsPath.EncodedPathString, Promise<unknown>>();

  constructor(
      manager: IsolatedFileSystemManager, path: Platform.DevToolsPath.UrlString,
      embedderPath: Platform.DevToolsPath.RawPathString, domFileSystem: FileSystem, type: PlatformFileSystemType,
      automatic: boolean) {
    super(path, type, automatic);
    this.manager = manager;
    this.#embedderPath = embedderPath;
    this.domFileSystem = domFileSystem;
    this.excludedFoldersSetting =
        Common.Settings.Settings.instance().createLocalSetting('workspace-excluded-folders', {});
    this.#excludedFolders = new Set(this.excludedFoldersSetting.get()[path] || []);
  }

  static async create(
      manager: IsolatedFileSystemManager, path: Platform.DevToolsPath.UrlString,
      embedderPath: Platform.DevToolsPath.RawPathString, type: PlatformFileSystemType, name: string, rootURL: string,
      automatic: boolean): Promise<IsolatedFileSystem|null> {
    const domFileSystem = Host.InspectorFrontendHost.InspectorFrontendHostInstance.isolatedFileSystem(name, rootURL);
    if (!domFileSystem) {
      return null;
    }

    const fileSystem = new IsolatedFileSystem(manager, path, embedderPath, domFileSystem, type, automatic);
    return await fileSystem.initializeFilePaths().then(() => fileSystem).catch(error => {
      console.error(error);
      return null;
    });
  }

  static errorMessage(error: DOMError): string {
    return i18nString(UIStrings.fileSystemErrorS, {PH1: error.message});
  }

  private serializedFileOperation<T>(path: Platform.DevToolsPath.EncodedPathString, operation: () => Promise<T>):
      Promise<T> {
    const promise = Promise.resolve(this.fileLocks.get(path)).then(() => operation.call(null));
    this.fileLocks.set(path, promise);
    return promise;
  }

  override getMetadata(path: Platform.DevToolsPath.EncodedPathString): Promise<Metadata|null> {
    const {promise, resolve} = Promise.withResolvers<Metadata|null>();
    this.domFileSystem.root.getFile(
        Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), undefined, fileEntryLoaded, errorHandler);
    return promise;

    function fileEntryLoaded(entry: FileEntry): void {
      entry.getMetadata(resolve, errorHandler);
    }

    function errorHandler(error: DOMError): void {
      const errorMessage = IsolatedFileSystem.errorMessage(error);
      console.error(errorMessage + ' when getting file metadata \'' + path);
      resolve(null);
    }
  }

  override initialFilePaths(): Platform.DevToolsPath.EncodedPathString[] {
    return [...this.#initialFilePaths];
  }

  override initialGitFolders(): Platform.DevToolsPath.EncodedPathString[] {
    return [...this.#initialGitFolders];
  }

  override embedderPath(): Platform.DevToolsPath.RawPathString {
    return this.#embedderPath;
  }

  private initializeFilePaths(): Promise<void> {
    return new Promise(fulfill => {
      let pendingRequests = 1;
      const boundInnerCallback = innerCallback.bind(this);
      this.requestEntries(Platform.DevToolsPath.EmptyRawPathString, boundInnerCallback);

      function innerCallback(this: IsolatedFileSystem, entries: FileEntry[]): void {
        for (let i = 0; i < entries.length; ++i) {
          const entry = entries[i];
          if (!entry.isDirectory) {
            if (this.isFileExcluded(Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
                    entry.fullPath as Platform.DevToolsPath.RawPathString))) {
              continue;
            }
            this.#initialFilePaths.add(Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
                Common.ParsedURL.ParsedURL.substr(entry.fullPath as Platform.DevToolsPath.RawPathString, 1)));
          } else {
            if (entry.fullPath.endsWith('/.git')) {
              const lastSlash = entry.fullPath.lastIndexOf('/');
              const parentFolder = Common.ParsedURL.ParsedURL.substr(
                  entry.fullPath as Platform.DevToolsPath.RawPathString, 1, lastSlash);
              this.#initialGitFolders.add(Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(parentFolder));
            }
            if (this.isFileExcluded(Common.ParsedURL.ParsedURL.concatenate(
                    Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
                        entry.fullPath as Platform.DevToolsPath.RawPathString),
                    '/'))) {
              const url = Common.ParsedURL.ParsedURL.concatenate(
                  this.path(),
                  Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
                      entry.fullPath as Platform.DevToolsPath.RawPathString));
              this.excludedEmbedderFolders.push(
                  Common.ParsedURL.ParsedURL.urlToRawPathString(url, Host.Platform.isWin()));
              continue;
            }
            ++pendingRequests;
            this.requestEntries(entry.fullPath as Platform.DevToolsPath.RawPathString, boundInnerCallback);
          }
        }
        if ((--pendingRequests === 0)) {
          fulfill();
        }
      }
    });
  }

  private async createFoldersIfNotExist(folderPath: Platform.DevToolsPath.RawPathString): Promise<DirectoryEntry|null> {
    // Fast-path. If parent directory already exists we return it immidiatly.
    let dirEntry = await new Promise<DirectoryEntry|null>(
        resolve => this.domFileSystem.root.getDirectory(folderPath, undefined, resolve, () => resolve(null)));
    if (dirEntry) {
      return dirEntry;
    }
    const paths = folderPath.split('/');
    let activePath = '';
    for (const path of paths) {
      activePath = activePath + '/' + path;
      dirEntry = await this.#createFolderIfNeeded(activePath);
      if (!dirEntry) {
        return null;
      }
    }
    return dirEntry;
  }

  #createFolderIfNeeded(path: string): Promise<DirectoryEntry|null> {
    return new Promise(resolve => {
      this.domFileSystem.root.getDirectory(path, {create: true}, dirEntry => resolve(dirEntry), error => {
        this.domFileSystem.root.getFile(
            path, undefined,
            () => this.dispatchEventToListeners(
                PlatformFileSystemEvents.FILE_SYSTEM_ERROR,
                i18nString(UIStrings.createDirFailedBecausePathIsFile, {PH1: path})),
            () => this.dispatchEventToListeners(
                PlatformFileSystemEvents.FILE_SYSTEM_ERROR, i18nString(UIStrings.createDirFailed, {PH1: path})));
        const errorMessage = IsolatedFileSystem.errorMessage(error);
        console.error(errorMessage + ' trying to create directory \'' + path + '\'');
        resolve(null);
      });
    });
  }

  override async createFile(
      path: Platform.DevToolsPath.EncodedPathString,
      name: Platform.DevToolsPath.RawPathString|null): Promise<Platform.DevToolsPath.EncodedPathString|null> {
    const dirEntry = await this.createFoldersIfNotExist(Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path));
    if (!dirEntry) {
      return null;
    }
    const fileEntry = await this.serializedFileOperation(
        path, createFileCandidate.bind(this, name || 'NewFile' as Platform.DevToolsPath.RawPathString));
    if (!fileEntry) {
      return null;
    }
    return Common.ParsedURL.ParsedURL.rawPathToEncodedPathString(
        Common.ParsedURL.ParsedURL.substr(fileEntry.fullPath as Platform.DevToolsPath.RawPathString, 1));

    function createFileCandidate(
        this: IsolatedFileSystem, name: Platform.DevToolsPath.RawPathString,
        newFileIndex?: number): Promise<FileEntry|null> {
      return new Promise(resolve => {
        const nameCandidate = Common.ParsedURL.ParsedURL.concatenate(name, (newFileIndex || '').toString());
        (dirEntry as DirectoryEntry).getFile(nameCandidate, {create: true, exclusive: true}, resolve, error => {
          if (error.name === 'InvalidModificationError') {
            resolve(createFileCandidate.call(this, name, (newFileIndex ? newFileIndex + 1 : 1)));
            return;
          }
          const errorMessage = IsolatedFileSystem.errorMessage(error);
          console.error(
              errorMessage + ' when testing if file exists \'' + (this.path() + '/' + path + '/' + nameCandidate) +
              '\'');
          resolve(null);
        });
      });
    }
  }

  override deleteFile(path: Platform.DevToolsPath.EncodedPathString): Promise<boolean> {
    const {promise, resolve} = Promise.withResolvers<boolean>();
    this.domFileSystem.root.getFile(
        Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), undefined, fileEntryLoaded.bind(this),
        errorHandler.bind(this));
    return promise;

    function fileEntryLoaded(this: IsolatedFileSystem, fileEntry: FileEntry): void {
      fileEntry.remove(fileEntryRemoved, errorHandler.bind(this));
    }

    function fileEntryRemoved(): void {
      resolve(true);
    }

    /**
     * TODO(jsbell): Update externs replacing DOMError with DOMException. https://crbug.com/496901
     */
    function errorHandler(this: IsolatedFileSystem, error: DOMError): void {
      const errorMessage = IsolatedFileSystem.errorMessage(error);
      console.error(errorMessage + ' when deleting file \'' + (this.path() + '/' + path) + '\'');
      resolve(false);
    }
  }

  override deleteDirectoryRecursively(path: Platform.DevToolsPath.EncodedPathString): Promise<boolean> {
    const {promise, resolve} = Promise.withResolvers<boolean>();
    this.domFileSystem.root.getDirectory(
        Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), undefined, dirEntryLoaded.bind(this),
        errorHandler.bind(this));
    return promise;

    function dirEntryLoaded(this: IsolatedFileSystem, dirEntry: DirectoryEntry): void {
      dirEntry.removeRecursively(dirEntryRemoved, errorHandler.bind(this));
    }

    function dirEntryRemoved(): void {
      resolve(true);
    }

    /**
     * TODO(jsbell): Update externs replacing DOMError with DOMException. https://crbug.com/496901
     */
    function errorHandler(this: IsolatedFileSystem, error: DOMError): void {
      const errorMessage = IsolatedFileSystem.errorMessage(error);
      console.error(errorMessage + ' when deleting directory \'' + (this.path() + '/' + path) + '\'');
      resolve(false);
    }
  }

  override requestFileBlob(path: Platform.DevToolsPath.EncodedPathString): Promise<Blob|null> {
    return new Promise(resolve => {
      this.domFileSystem.root.getFile(Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), undefined, entry => {
        entry.file(resolve, errorHandler.bind(this));
      }, errorHandler.bind(this));

      function errorHandler(this: IsolatedFileSystem, error: DOMError): void {
        if (error.name === 'NotFoundError') {
          resolve(null);
          return;
        }

        const errorMessage = IsolatedFileSystem.errorMessage(error);
        console.error(errorMessage + ' when getting content for file \'' + (this.path() + '/' + path) + '\'');
        resolve(null);
      }
    });
  }

  override requestFileContent(path: Platform.DevToolsPath.EncodedPathString):
      Promise<TextUtils.ContentData.ContentDataOrError> {
    return this.serializedFileOperation(path, () => this.innerRequestFileContent(path));
  }

  private async innerRequestFileContent(path: Platform.DevToolsPath.EncodedPathString):
      Promise<TextUtils.ContentData.ContentDataOrError> {
    const blob = await this.requestFileBlob(path);
    if (!blob) {
      return {error: i18nString(UIStrings.blobCouldNotBeLoaded)};
    }

    const mimeType = mimeTypeForBlob(path, blob);
    try {
      if (Platform.MimeType.isTextType(mimeType)) {
        return new TextUtils.ContentData.ContentData(await blob.text(), /* isBase64 */ false, mimeType);
      }
      return new TextUtils.ContentData.ContentData(await Common.Base64.encode(blob), /* isBase64 */ true, mimeType);
    } catch (e) {
      return {error: i18nString(UIStrings.cantReadFileSS, {PH1: path, PH2: e.message})};
    }
  }

  override async setFileContent(path: Platform.DevToolsPath.EncodedPathString, content: string, isBase64: boolean):
      Promise<void> {
    Host.userMetrics.actionTaken(Host.UserMetrics.Action.FileSavedInWorkspace);
    let resolve: (result: ProgressEvent<EventTarget>|undefined) => void;
    const innerSetFileContent = (): Promise<ProgressEvent<EventTarget>|undefined> => {
      const promise = new Promise<ProgressEvent<EventTarget>|undefined>(x => {
        resolve = x;
      });
      this.domFileSystem.root.getFile(
          Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), {create: true}, fileEntryLoaded.bind(this),
          errorHandler.bind(this));
      return promise;
    };

    void this.serializedFileOperation(path, innerSetFileContent);

    function fileEntryLoaded(this: IsolatedFileSystem, entry: FileEntry): void {
      entry.createWriter(fileWriterCreated.bind(this), errorHandler.bind(this));
    }

    async function fileWriterCreated(this: IsolatedFileSystem, fileWriter: FileWriter): Promise<void> {
      fileWriter.onerror = errorHandler.bind(this);
      fileWriter.onwriteend = fileWritten;
      let blob: Blob;
      if (isBase64) {
        blob = await (await fetch(`data:application/octet-stream;base64,${content}`)).blob();
      } else {
        blob = new Blob([content], {type: 'text/plain'});
      }
      fileWriter.write(blob);

      function fileWritten(): void {
        fileWriter.onwriteend = resolve;
        fileWriter.truncate(blob.size);
      }
    }

    function errorHandler(this: IsolatedFileSystem, error: DOMError|ProgressEvent<EventTarget>): void {
      // @ts-expect-error TODO(crbug.com/1172300) Properly type this after jsdoc to ts migration
      const errorMessage = IsolatedFileSystem.errorMessage(error);
      console.error(errorMessage + ' when setting content for file \'' + (this.path() + '/' + path) + '\'');
      resolve(undefined);
    }
  }

  override renameFile(
      path: Platform.DevToolsPath.EncodedPathString, newName: Platform.DevToolsPath.RawPathString,
      callback: (arg0: boolean, arg1?: string|undefined) => void): void {
    newName = newName ? Common.ParsedURL.ParsedURL.trim(newName) : newName;
    if (!newName || newName.indexOf('/') !== -1) {
      callback(false);
      return;
    }
    let fileEntry: FileEntry;
    let dirEntry: DirectoryEntry;

    this.domFileSystem.root.getFile(
        Common.ParsedURL.ParsedURL.encodedPathToRawPathString(path), undefined, fileEntryLoaded.bind(this),
        errorHandler.bind(this));

    function fileEntryLoaded(this: IsolatedFileSystem, entry: FileEntry): void {
      if (entry.name === newName) {
        callback(false);
        return;
      }

      fileEntry = entry;
      fileEntry.getParent(dirEntryLoaded.bind(this), errorHandler.bind(this));
    }

    function dirEntryLoaded(this: IsolatedFileSystem, entry: DirectoryEntry): void {
      dirEntry = entry;
      dirEntry.getFile(newName, undefined, newFileEntryLoaded, newFileEntryLoadErrorHandler.bind(this));
    }

    function newFileEntryLoaded(_entry: FileEntry): void {
      callback(false);
    }

    function newFileEntryLoadErrorHandler(this: IsolatedFileSystem, error: DOMError): void {
      if (error.name !== 'NotFoundError') {
        callback(false);
        return;
      }
      fileEntry.moveTo(dirEntry, newName, fileRenamed, errorHandler.bind(this));
    }

    function fileRenamed(entry: Entry): void {
      callback(true, entry.name);
    }

    function errorHandler(this: IsolatedFileSystem, error: DOMError): void {
      const errorMessage = IsolatedFileSystem.errorMessage(error);
      console.error(errorMessage + ' when renaming file \'' + (this.path() + '/' + path) + '\' to \'' + newName + '\'');
      callback(false);
    }
  }

  private readDirectory(dirEntry: DirectoryEntry, callback: (arg0: FileEntry[]) => void): void {
    const dirReader = dirEntry.createReader();
    let entries: FileEntry[] = [];

    function innerCallback(results: Entry[]): void {
      if (!results.length) {
        callback(entries.sort());
      } else {
        entries = entries.concat(toArray(results));
        dirReader.readEntries(innerCallback, errorHandler);
      }
    }

    function toArray(list: Entry[]): FileEntry[] {
      return Array.prototype.slice.call(list || [], 0);
    }

    dirReader.readEntries(innerCallback, errorHandler);

    function errorHandler(error: DOMError): void {
      const errorMessage = IsolatedFileSystem.errorMessage(error);
      console.error(errorMessage + ' when reading directory \'' + dirEntry.fullPath + '\'');
      callback([]);
    }
  }

  private requestEntries(path: Platform.DevToolsPath.RawPathString, callback: (arg0: FileEntry[]) => void): void {
    this.domFileSystem.root.getDirectory(path, undefined, innerCallback.bind(this), errorHandler);

    function innerCallback(this: IsolatedFileSystem, dirEntry: DirectoryEntry): void {
      this.readDirectory(dirEntry, callback);
    }

    function errorHandler(error: DOMError): void {
      const errorMessage = IsolatedFileSystem.errorMessage(error);
      console.error(errorMessage + ' when requesting entry \'' + path + '\'');
      callback([]);
    }
  }

  private saveExcludedFolders(): void {
    const settingValue = this.excludedFoldersSetting.get();
    settingValue[this.path()] = [...this.#excludedFolders];
    this.excludedFoldersSetting.set(settingValue);
  }

  override addExcludedFolder(path: Platform.DevToolsPath.EncodedPathString): void {
    this.#excludedFolders.add(path);
    this.saveExcludedFolders();
    this.manager.dispatchEventToListeners(Events.ExcludedFolderAdded, path);
  }

  override removeExcludedFolder(path: Platform.DevToolsPath.EncodedPathString): void {
    this.#excludedFolders.delete(path);
    this.saveExcludedFolders();
    this.manager.dispatchEventToListeners(Events.ExcludedFolderRemoved, path);
  }

  override fileSystemRemoved(): void {
    const settingValue = this.excludedFoldersSetting.get();
    delete settingValue[this.path()];
    this.excludedFoldersSetting.set(settingValue);
  }

  override isFileExcluded(folderPath: Platform.DevToolsPath.EncodedPathString): boolean {
    if (this.#excludedFolders.has(folderPath)) {
      return true;
    }
    const regex = (this.manager.workspaceFolderExcludePatternSetting()).asRegExp();
    return Boolean(regex?.test(Common.ParsedURL.ParsedURL.encodedPathToRawPathString(folderPath)));
  }

  override excludedFolders(): Set<Platform.DevToolsPath.EncodedPathString> {
    return this.#excludedFolders;
  }

  override searchInPath(query: string, progress: Common.Progress.Progress): Promise<string[]> {
    return new Promise(resolve => {
      const requestId = this.manager.registerCallback(innerCallback);
      Host.InspectorFrontendHost.InspectorFrontendHostInstance.searchInPath(requestId, this.#embedderPath, query);

      function innerCallback(files: Platform.DevToolsPath.RawPathString[]): void {
        resolve(files.map(path => Common.ParsedURL.ParsedURL.rawPathToUrlString(path)));
        ++progress.worked;
      }
    });
  }

  override indexContent(progress: Common.Progress.Progress): void {
    progress.totalWork = 1;
    const requestId = this.manager.registerProgress(progress);
    Host.InspectorFrontendHost.InspectorFrontendHostInstance.indexPath(
        requestId, this.#embedderPath, JSON.stringify(this.excludedEmbedderFolders));
  }

  override mimeFromPath(path: Platform.DevToolsPath.UrlString): string {
    return Common.ResourceType.ResourceType.mimeFromURL(path) || 'text/plain';
  }

  override canExcludeFolder(path: Platform.DevToolsPath.EncodedPathString): boolean {
    return Boolean(path) && this.type() !== PlatformFileSystemType.OVERRIDES;
  }

  // path not typed as Branded Types as here we are interested in extention only
  override contentType(path: string): Common.ResourceType.ResourceType {
    const extension = Common.ParsedURL.ParsedURL.extractExtension(path);
    if (STYLE_SHEET_EXTENSIONS.has(extension)) {
      return Common.ResourceType.resourceTypes.Stylesheet;
    }
    if (DOCUMENT_EXTENSIONS.has(extension)) {
      return Common.ResourceType.resourceTypes.Document;
    }
    if (IMAGE_EXTENSIONS.has(extension)) {
      return Common.ResourceType.resourceTypes.Image;
    }
    if (SCRIPT_EXTENSIONS.has(extension)) {
      return Common.ResourceType.resourceTypes.Script;
    }
    return BinaryExtensions.has(extension) ? Common.ResourceType.resourceTypes.Other :
                                             Common.ResourceType.resourceTypes.Document;
  }

  override tooltipForURL(url: Platform.DevToolsPath.UrlString): string {
    const path = Platform.StringUtilities.trimMiddle(
        Common.ParsedURL.ParsedURL.urlToRawPathString(url, Host.Platform.isWin()), 150);
    return i18nString(UIStrings.linkedToS, {PH1: path});
  }

  override supportsAutomapping(): boolean {
    return this.type() !== PlatformFileSystemType.OVERRIDES;
  }
}

/**
 * @returns Tries to determine the mime type for this Blob:
 *   1) If blob.type is non-empty, we return that.
 *   2) If we know it from the extension, use that.
 *   3) Check the list of known binary extensions and use application/octet-stream.
 *   4) Use text/plain
 */
function mimeTypeForBlob(path: Platform.DevToolsPath.EncodedPathString, blob: Blob): string {
  if (blob.type) {
    return blob.type;
  }

  const extension = Common.ParsedURL.ParsedURL.extractExtension(path);
  const maybeMime = Common.ResourceType.ResourceType.mimeFromExtension(extension);
  if (maybeMime) {
    return maybeMime;
  }

  return BinaryExtensions.has(extension) ? 'application/octet-stream' : 'text/plain';
}

const STYLE_SHEET_EXTENSIONS = new Set<string>(['css', 'scss', 'sass', 'less']);
const DOCUMENT_EXTENSIONS = new Set<string>(['htm', 'html', 'asp', 'aspx', 'phtml', 'jsp']);

const SCRIPT_EXTENSIONS = new Set<string>([
  'asp', 'aspx', 'c', 'cc', 'cljs', 'coffee', 'cpp', 'cs', 'dart', 'java', 'js',
  'jsp', 'jsx',  'h', 'm',  'mjs',  'mm',     'py',  'sh', 'ts',   'tsx',  'ls',
]);

const IMAGE_EXTENSIONS = new Set<string>(['jpeg', 'jpg', 'svg', 'gif', 'webp', 'png', 'ico', 'tiff', 'tif', 'bmp']);

export const BinaryExtensions = new Set<string>([
  // Executable extensions, roughly taken from https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats
  'cmd',
  'com',
  'exe',
  // Archive extensions, roughly taken from https://en.wikipedia.org/wiki/List_of_archive_formats
  'a',
  'ar',
  'iso',
  'tar',
  'bz2',
  'gz',
  'lz',
  'lzma',
  'z',
  '7z',
  'apk',
  'arc',
  'cab',
  'dmg',
  'jar',
  'pak',
  'rar',
  'zip',
  // Audio file extensions, roughly taken from https://en.wikipedia.org/wiki/Audio_file_format#List_of_formats
  '3gp',
  'aac',
  'aiff',
  'flac',
  'm4a',
  'mmf',
  'mp3',
  'ogg',
  'oga',
  'raw',
  'sln',
  'wav',
  'wma',
  'webm',
  // Video file extensions, roughly taken from https://en.wikipedia.org/wiki/Video_file_format
  'mkv',
  'flv',
  'vob',
  'ogv',
  'gifv',
  'avi',
  'mov',
  'qt',
  'mp4',
  'm4p',
  'm4v',
  'mpg',
  'mpeg',
  // Image file extensions
  'jpeg',
  'jpg',
  'gif',
  'webp',
  'png',
  'ico',
  'tiff',
  'tif',
  'bmp',
]);
