text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.testing = exports.refreshCacheEntries = exports.loadDictionary = void 0;
  const wordListHelper_1 = require("../wordListHelper");
  const SpellingDictionary_1 = require("./SpellingDictionary");
  const path = require("path");
  const gensequence_1 = require("gensequence");
  const fileReader_1 = require("../util/fileReader");
  const fs = require("fs-extra");
  const MAX_AGE = 10000;
  const loaders = {
      S: loadSimpleWordList,
      C: loadCodeWordList,
      T: loadTrie,
      default: loadSimpleWordList,
  };
  const dictionaryCache = new Map();
  function loadDictionary(uri, options) {
      const key = calcKey(uri, options);
      if (!dictionaryCache.has(key)) {
          dictionaryCache.set(key, loadEntry(uri, options));
      }
      const entry = dictionaryCache.get(key);
      return entry.dictionary;
  }
  exports.loadDictionary = loadDictionary;
  function calcKey(uri, options) {
      const loaderType = determineType(uri, options);
      return [uri, loaderType].join('|');
  }
  async function refreshCacheEntries(maxAge = MAX_AGE, now = Date.now()) {
      await Promise.all([...dictionaryCache]
          .map(([, entry]) => refreshEntry(entry, maxAge, now)));
  }
  exports.refreshCacheEntries = refreshCacheEntries;
  async function refreshEntry(entry, maxAge = MAX_AGE, now = Date.now()) {
      if (now - entry.ts >= maxAge) {
          // Write to the ts, so the next one will not do it.
          entry.ts = now;
          const pStat = fs.stat(entry.uri).catch(() => undefined);
          const [state, oldState] = await Promise.all([pStat, entry.state]);
          if (entry.ts === now && ((state === null || state === void 0 ? void 0 : state.mtimeMs) !== (oldState === null || oldState === void 0 ? void 0 : oldState.mtimeMs) ||
              (state === null || state === void 0 ? void 0 : state.size) !== (oldState === null || oldState === void 0 ? void 0 : oldState.size))) {
              dictionaryCache.set(calcKey(entry.uri, entry.options), loadEntry(entry.uri, entry.options));
          }
      }
  }
  function loadEntry(uri, options, now = Date.now()) {
      const dictionary = load(uri, options).catch(() => SpellingDictionary_1.createSpellingDictionary([], path.basename(uri), uri, options));
      return {
          uri,
          options,
          ts: now,
          state: fs.stat(uri).catch(() => undefined),
          dictionary,
      };
  }
  function determineType(uri, options) {
      const defType = uri.endsWith('.trie.gz') ? 'T' : uri.endsWith('.txt.gz') ? 'S' : 'C';
      const { type = defType } = options;
      const regTrieTest = /\.trie\b/i;
      return regTrieTest.test(uri) ? 'T' : type;
  }
  function load(uri, options) {
      const type = determineType(uri, options);
      const loader = loaders[type] || loaders.default;
      return loader(uri, options);
  }
  async function loadSimpleWordList(filename, options) {
      const lines = await fileReader_1.readLines(filename);
      return SpellingDictionary_1.createSpellingDictionary(lines, path.basename(filename), filename, options);
  }
  async function loadCodeWordList(filename, options) {
      const lines = gensequence_1.genSequence(await fileReader_1.readLines(filename));
      const words = lines.concatMap(wordListHelper_1.splitLineIntoCodeWords);
      return SpellingDictionary_1.createSpellingDictionary(words, path.basename(filename), filename, options);
  }
  async function loadTrie(filename, options) {
      return SpellingDictionary_1.createSpellingDictionaryTrie(await wordListHelper_1.loadWordsNoError(filename), path.basename(filename), filename, options);
  }
  exports.testing = {
      dictionaryCache,
      refreshEntry,
      loadEntry,
      load
  };
  //# sourceMappingURL=DictionaryLoader.js.map