"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.getI18nLoadingRuntimeModule = getI18nLoadingRuntimeModule;

/* eslint-disable no-restricted-syntax */
const getChunksMapObject = i18nChunks => {
  const obj = {};

  for (const chunk of i18nChunks) {
    obj[chunk.id] = 1;
  }

  return obj;
};

function getI18nLoadingRuntimeModule({
  webpack,
  getI18nChunks
}) {
  const {
    Template,
    RuntimeGlobals,
    RuntimeModule
  } = webpack;

  class I18nLoadingRuntimeModule extends RuntimeModule {
    constructor(runtimeRequirements, {
      runtimeOptions,
      prefixFunc
    }) {
      super('i18n loading', 10);
      this.runtimeRequirements = runtimeRequirements;
      this.prefixFunc = prefixFunc;
      this.runtimeOptions = runtimeOptions;
    }

    generate() {
      const {
        chunk,
        runtimeRequirements,
        prefixFunc,
        compilation
      } = this;
      const {
        runtimeTemplate,
        outputOptions: {
          crossOriginLoading
        }
      } = compilation; // const i18nChunks = getI18nChunks(chunk, compilation);
      // REASON: we do it in here is in dev mode thing may change
      // const i18nChunks = getI18nChunks(entryRuntimeChunk);

      const i18nChunks = getI18nChunks(chunk);
      const withLoading = runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers) && i18nChunks.length > 0;

      if (!withLoading) {
        return '';
      }

      const chunkMap = getChunksMapObject(i18nChunks);
      const {
        attributes,
        scriptType,
        insert: insertRoot
      } = this.runtimeOptions;
      const insertPlace = typeof insertRoot === 'function' ? `(${insertRoot.toString()})(scriptTag)` : Template.asString([`var target = document.querySelector("${insertRoot}");`, 'target.parentNode.insertBefore(scriptTag, target.nextSibling);']);
      return Template.asString([`${prefixFunc(i18nChunks)}`, `var createI18nScriptTag = ${runtimeTemplate.basicFunction('chunkId, fullsrc, resolve, reject', ['var scriptTag = document.createElement("script");', attributes ? Template.asString(Object.entries(attributes).map(entry => {
        const [key, value] = entry;
        return `scriptTag.setAttribute(${JSON.stringify(key)}, ${JSON.stringify(value)});`;
      })) : '', scriptType ? `scriptTag.type = ${JSON.stringify(scriptType)};` : '', `var onScriptComplete = ${runtimeTemplate.basicFunction('event', ['// avoid mem leaks.', 'scriptTag.onerror = scriptTag.onload = null;', 'if (event.type === \'load\') {', Template.indent(['resolve();']), '} else {', Template.indent(['var errorType = event && (event.type === \'load\' ? \'missing\' : event.type);', 'var realSrc = event && event.target && event.target.src || fullsrc;', 'var err = new Error("Loading I18N chunk " + chunkId + " failed.\\n(" + realSrc + ")");', 'err.code = "I18N_CHUNK_LOAD_FAILED";', 'err.type = errorType;', 'err.request = realSrc;', 'scriptTag.parentNode.removeChild(scriptTag)', 'reject(err);']), '}'])}`, 'scriptTag.onerror = scriptTag.onload = onScriptComplete;', 'scriptTag.src = fullsrc;', crossOriginLoading ? Template.asString(['if (scriptTag.src.indexOf(window.location.origin + \'/\') !== 0) {', Template.indent(`scriptTag.crossOrigin = ${JSON.stringify(crossOriginLoading)};`), '}']) : '', insertRoot && insertPlace || Template.asString(['document.head.appendChild(scriptTag);']), 'return scriptTag;'])};`, `var findI18nScriptTag = ${runtimeTemplate.basicFunction('src, fullsrc', ['var existingScriptTags = document.getElementsByTagName("script");', 'for(var i = 0; i < existingScriptTags.length; i++) {', Template.indent(['var tag = existingScriptTags[i];', 'var dataSrc = tag.getAttribute("data-src") || tag.getAttribute("src");', 'if((dataSrc === src || dataSrc === fullsrc)) return tag;']), '}', 'var existingStyleTags = document.getElementsByTagName("style");', 'for(var i = 0; i < existingStyleTags.length; i++) {', Template.indent(['var tag = existingStyleTags[i];', 'var dataSrc = tag.getAttribute("data-src");', 'if(dataSrc === src || dataSrc === fullsrc) return tag;']), '}'])};`, `var loadI18nScriptTag = ${runtimeTemplate.basicFunction('chunkId', `return new Promise(${runtimeTemplate.basicFunction('resolve, reject', [`var src = ${RuntimeGlobals.require}.miniI18nF(chunkId);`, `var fullsrc = ${RuntimeGlobals.publicPath} + src;`, 'if(findI18nScriptTag(src, fullsrc)) return resolve();', 'createI18nScriptTag(chunkId, fullsrc, resolve, reject);'])});`)}`, withLoading ? Template.asString(['// object to store loaded I18N chunks', 'var installedI18nChunks = {', Template.indent(
      /** @type {string[]} */
      chunk.ids.map(id => `${JSON.stringify(id)}: 0`).join(',\n')), '};', '', `${RuntimeGlobals.ensureChunkHandlers}.miniI18n = ${runtimeTemplate.basicFunction('chunkId, promises', [`var i18nChunks = ${JSON.stringify(chunkMap)};`, 'if(installedI18nChunks[chunkId]) promises.push(installedI18nChunks[chunkId]);', 'else if(installedI18nChunks[chunkId] !== 0 && i18nChunks[chunkId]) {', Template.indent([`promises.push(installedI18nChunks[chunkId] = loadI18nScriptTag(chunkId).then(${runtimeTemplate.basicFunction('', 'installedI18nChunks[chunkId] = 0;')}, ${runtimeTemplate.basicFunction('e', ['delete installedI18nChunks[chunkId];', 'throw e;'])}));`]), '}'])};`]) : '// no chunk loading', '']);
    }

  }

  return I18nLoadingRuntimeModule;
}