"use strict";

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

var _utils = require("./utils");

var _webpack = require("webpack");

var _I18nKeysIdentifer = _interopRequireDefault(require("./I18nKeysIdentifer"));

var _I18nFilesEmitter = _interopRequireDefault(require("./I18nFilesEmitter"));

var _I18nDownlodLogic = _interopRequireDefault(require("./I18nDownlodLogic"));

var _getI18nKeysFormModules = _interopRequireDefault(require("./utils/getI18nKeysFormModules"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

// #region initial

/**
 * @TODO:
 *  [?] add comment line options for properties file and get all keys form property file do right way to genarate them
 *  [?] need to discuss with collectI18n Keys with js comment need to conform "what is the comment? "
 */

/**
 * Notes: this plugin has done below works
 *  1. collect I18n Keys from js files and make it as Depenencies
 *  2. we create file(asset) for chunk specific i18nChunk Files
 *  3. create hash for the specific i18nChunk Files
 *  4. write logic to requireEnsure method for dowlod I18n chunk download dynamicaly
 *  5. create manifest.json file which has the mapping of  chunk-locales-i18nChunkFile
 *       for the external referrece.
 * Hints :-
 *   - file  means your machine files
 *   - asset means that also  file but that will create by webpack after build
 */
// const getI18nLocales = require('./utils/getI18nLocales');
// const { ConcatSource, SourceMapSource, OriginalSource } = sources;
const {
  createHash
} = _webpack.util;
const MODULE_TYPE = 'json/i18n';

const i18ntype = locale => `${MODULE_TYPE}/${locale}`;

const pluginName = 'i18n-plugin';
/**
 * @typedef I18nPluginOptions
 * @property {String} filenameTemplate this was template for i18n chunk
 * @property {String} jsResource this was path for jsResource i18n file
 * @property {String} propertiesFolder this was path for propertiesFolder i18n file
 * @property {Boolean} disableDefault this option for disable defulat value  for i18n keys, means if the language file does not have some key we don't give jsResource value
 * @property {String} i18nManifestFileName this was ouput path for i18n manifest.
 * @property {String} jsonpFunc this was function name, we will  call  that function everytime i18n chunk download.
 * @property {String} localeVarName this was variable name, we will call that function everytime i18n chunk download.
 * 
 */

class I18nPlugin {
  constructor(options = {}) {
    // initialize options
    this.options = Object.assign({
      filenameTemplate: 'i18n/[locale]/[name].i18n.js'
    }, options);
    const {
      filenameTemplate,
      publicPath,
      localeVarName,
      i18nManifestFileName,
      disableDefault,
      jsResource,
      propertiesFolder,
      jsonpFunc
    } = this.options;
    this.publicPath = publicPath; // gethere i18n keys and values

    this.jsResourceI18nKeys = jsResource ? (0, _utils.getPropertiesAsJSON)(jsResource) : {};
    this.allI18nObject = (0, _utils.getAllI18n)({
      folderPath: propertiesFolder,
      disableDefault,
      jsResourceI18nKeys: this.jsResourceI18nKeys
    }); // initialize base data's and plugis

    this.locales = Object.keys(this.allI18nObject);
    this.i18nKeysIdentifer = new _I18nKeysIdentifer.default(this.jsResourceI18nKeys);
    this.i18nFilesEmitter = new _I18nFilesEmitter.default({
      allI18nObject: this.allI18nObject,
      locales: this.locales,
      i18nManifestFileName,
      filenameTemplate,
      jsonpFunc
    });
    this.i18nDownlodLogic = new _I18nDownlodLogic.default({
      filenameTemplate,
      publicPath,
      locales: this.locales,
      localeVarName
    });
  }

  maintainHashForAllI18nAssets(compilation) {
    /**
     * we write chunkHash logic inside of our plugin Because we only add Dependency not Module.
     *  So we need to update chunkHash for our assets
     *  and we not able tell with just Modules.
     *  Because, if we add Module for the Depenentcy then that module must has some hash.
     *  But our I18n Hash is no module specific it was chunk specific,
     *  that's why we do the stuf in the chunkHash hook.
     */
    compilation.hooks.chunkHash.tap(pluginName, (chunk, chunkHash) => {
      const {
        outputOptions
      } = compilation;
      const {
        hashFunction,
        hashDigest,
        hashDigestLength
      } = outputOptions;
      const i18nKeys = (0, _getI18nKeysFormModules.default)(chunk.modulesIterable);

      if (!i18nKeys.length) {
        return;
      }

      const {
        contentHash
      } = chunk; // contentHash = {
      //   javascript: 'abcd2938',
      //   'css/mini-extract': 'askdijasod'
      // };

      this.locales.forEach(locale => {
        const contentHashStr = createHash(hashFunction).update(this.i18nFilesEmitter.getTemplateString(i18nKeys, locale)).digest(hashDigest);
        contentHash[i18ntype(locale)] = contentHashStr.substring(0, hashDigestLength);
        chunkHash.update(contentHashStr);
      });
    });
  }

  apply(compiler) {
    this.i18nKeysIdentifer.apply(compiler);
    compiler.hooks.thisCompilation.tap(pluginName, compilation => {
      // this below  hook was tapped for hash for the specific i18nChunk Files and write logic to requireEnsure
      this.maintainHashForAllI18nAssets(compilation); // const { mainTemplate } = compilation;
      // this.addDownloadLogicOfI18nInMainTemplate(mainTemplate);
    });
    this.i18nFilesEmitter.apply(compiler);
    this.i18nDownlodLogic.apply(compiler);
  }

}
/*
        // TODO:  need to reimplement this logic
        // NOTE:  this logic for split all content hash per mani chunk
        // like add chunk content hash to  main locale i18n file

        // let isEntry = chunk.name === this.options.mainChunkName;
        // if (chunk.name === 'main' && chunk.hasEntryModule()) {
        if (isEntry) {
          const hashSource = new ConcatSource();
        const dummyChunk = new chunk.constructor();
          hashSource.add('// it wil be I18N file hash');
          const templateHooks = compilation.chunkTemplate.hooks;
          let c = templateHooks.render.call(
            templateHooks.module.call(
              hashSource,
              dummyChunk,
              compilation.moduleTemplate.javascript,
              compilation.dependencyTemplates
            ),
            dummyChunk,
            compilation.moduleTemplate.javascript,
            compilation.dependencyTemplates
          );
          
        }
        */


exports.default = I18nPlugin;