"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const glob = require("../../../base/common/glob.js");
const mime = require("../../../base/common/mime.js");
const network = require("../../../base/common/network.js");
const path = require("../../../base/common/path.js");
const resources = require("../../../base/common/resources.js");
const strings = require("../../../base/common/strings.js");
let registeredAssociations = [];
let nonUserRegisteredAssociations = [];
let userRegisteredAssociations = [];
function registerPlatformLanguageAssociation(association, warnOnOverwrite = false) {
  _registerLanguageAssociation(association, false, warnOnOverwrite);
}
function _registerLanguageAssociation(association, userConfigured, warnOnOverwrite) {
  const associationItem = toLanguageAssociationItem(association, userConfigured);
  registeredAssociations.push(associationItem);
  if (!associationItem.userConfigured) {
    nonUserRegisteredAssociations.push(associationItem);
  } else {
    userRegisteredAssociations.push(associationItem);
  }
  if (warnOnOverwrite && !associationItem.userConfigured) {
    registeredAssociations.forEach((a) => {
      if (a.mime === associationItem.mime || a.userConfigured) {
        return;
      }
      if (associationItem.extension && a.extension === associationItem.extension) {
        console.warn(`Overwriting extension <<${associationItem.extension}>> to now point to mime <<${associationItem.mime}>>`);
      }
      if (associationItem.filename && a.filename === associationItem.filename) {
        console.warn(`Overwriting filename <<${associationItem.filename}>> to now point to mime <<${associationItem.mime}>>`);
      }
      if (associationItem.filepattern && a.filepattern === associationItem.filepattern) {
        console.warn(`Overwriting filepattern <<${associationItem.filepattern}>> to now point to mime <<${associationItem.mime}>>`);
      }
      if (associationItem.firstline && a.firstline === associationItem.firstline) {
        console.warn(`Overwriting firstline <<${associationItem.firstline}>> to now point to mime <<${associationItem.mime}>>`);
      }
    });
  }
}
function toLanguageAssociationItem(association, userConfigured) {
  return {
    id: association.id,
    mime: association.mime,
    filename: association.filename,
    extension: association.extension,
    filepattern: association.filepattern,
    firstline: association.firstline,
    userConfigured,
    filenameLowercase: association.filename ? association.filename.toLowerCase() : void 0,
    extensionLowercase: association.extension ? association.extension.toLowerCase() : void 0,
    filepatternLowercase: association.filepattern ? glob.parse(association.filepattern.toLowerCase()) : void 0,
    filepatternOnPath: association.filepattern ? association.filepattern.indexOf(path.posix.sep) >= 0 : false
  };
}
function clearPlatformLanguageAssociations() {
  registeredAssociations = registeredAssociations.filter((a) => a.userConfigured);
  nonUserRegisteredAssociations = [];
}
function getMimeTypes(resource, firstLine) {
  let path$1;
  if (resource) {
    switch (resource.scheme) {
      case network.Schemas.file:
        path$1 = resource.fsPath;
        break;
      case network.Schemas.data: {
        const metadata = resources.DataUri.parseMetaData(resource);
        path$1 = metadata.get(resources.DataUri.META_DATA_LABEL);
        break;
      }
      default:
        path$1 = resource.path;
    }
  }
  if (!path$1) {
    return [mime.Mimes.unknown];
  }
  path$1 = path$1.toLowerCase();
  const filename = path.basename(path$1);
  const configuredLanguage = getMimeByPath(path$1, filename, userRegisteredAssociations);
  if (configuredLanguage) {
    return [configuredLanguage, mime.Mimes.text];
  }
  const registeredLanguage = getMimeByPath(path$1, filename, nonUserRegisteredAssociations);
  if (registeredLanguage) {
    return [registeredLanguage, mime.Mimes.text];
  }
  if (firstLine) {
    const firstlineLanguage = getMimeByFirstline(firstLine);
    if (firstlineLanguage) {
      return [firstlineLanguage, mime.Mimes.text];
    }
  }
  return [mime.Mimes.unknown];
}
function getMimeByPath(path2, filename, associations) {
  var _a;
  let filenameMatch = void 0;
  let patternMatch = void 0;
  let extensionMatch = void 0;
  for (let i = associations.length - 1; i >= 0; i--) {
    const association = associations[i];
    if (filename === association.filenameLowercase) {
      filenameMatch = association;
      break;
    }
    if (association.filepattern) {
      if (!patternMatch || association.filepattern.length > patternMatch.filepattern.length) {
        const target = association.filepatternOnPath ? path2 : filename;
        if ((_a = association.filepatternLowercase) === null || _a === void 0 ? void 0 : _a.call(association, target)) {
          patternMatch = association;
        }
      }
    }
    if (association.extension) {
      if (!extensionMatch || association.extension.length > extensionMatch.extension.length) {
        if (filename.endsWith(association.extensionLowercase)) {
          extensionMatch = association;
        }
      }
    }
  }
  if (filenameMatch) {
    return filenameMatch.mime;
  }
  if (patternMatch) {
    return patternMatch.mime;
  }
  if (extensionMatch) {
    return extensionMatch.mime;
  }
  return void 0;
}
function getMimeByFirstline(firstLine) {
  if (strings.startsWithUTF8BOM(firstLine)) {
    firstLine = firstLine.substr(1);
  }
  if (firstLine.length > 0) {
    for (let i = registeredAssociations.length - 1; i >= 0; i--) {
      const association = registeredAssociations[i];
      if (!association.firstline) {
        continue;
      }
      const matches = firstLine.match(association.firstline);
      if (matches && matches.length > 0) {
        return association.mime;
      }
    }
  }
  return void 0;
}
exports.clearPlatformLanguageAssociations = clearPlatformLanguageAssociations;
exports.getMimeTypes = getMimeTypes;
exports.registerPlatformLanguageAssociation = registerPlatformLanguageAssociation;
