"use strict";
exports.registerTaglib = registerTaglib;
exports.buildLookup = buildLookup;
exports.clearCache = clearCache;

var taglibLoader;
var taglibFinder;
var TaglibLookup;

exports.registeredTaglibs = [];

var lookupCache = {};

function handleImports(lookup, taglib) {
  if (taglib.imports) {
    for (var i = 0; i < taglib.imports.length; i++) {
      var importedTaglib = taglib.imports[i];

      if (!lookup.hasTaglib(importedTaglib)) {
        lookup.addTaglib(importedTaglib);
      }
    }
  }
}

function buildLookup(dirname) {
  var taglibs = taglibFinder.find(dirname, exports.registeredTaglibs);

  var lookupCacheKey = taglibs
    .map(function(taglib) {
      return taglib.id;
    })
    .join(",");

  var lookup = lookupCache[lookupCacheKey];
  if (lookup === undefined) {
    lookup = new TaglibLookup();
    // The taglibs "closer" to the template will be earlier in the list
    // and the taglibs "farther" from the template will be later. We
    // want closer taglibs to take precedence (especially when de-duping)
    // so we loop from beginning to end. We used to loop from the end
    // to the beginning, but that appears to have been a mistake.
    for (var i = 0; i < taglibs.length; i++) {
      var taglib = taglibs[i];
      lookup.addTaglib(taglib);
      handleImports(lookup, taglib);
    }

    lookupCache[lookupCacheKey] = lookup;
  }

  return lookup;
}

function registerTaglib(taglib) {
  if (typeof taglib === "string") {
    let taglibPath = taglib;
    taglib = taglibLoader.loadFromFile(taglibPath);
  }

  exports.registeredTaglibs.push(taglib);
}

function clearCache() {
  lookupCache = {};
}

taglibLoader = require("../taglib-loader");
taglibFinder = require("../taglib-finder");
TaglibLookup = require("./TaglibLookup");
