"use strict";

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

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

/* eslint-disable max-classes-per-file */
// import { I18nDependency } from './1I18nDependency';
const pluginName = 'I18nKeysIdentifer';
/**
 * this plugin search the i18 keys and make it as I18nDependency.
 * how it works?
 *  this plugin get jsResourceI18nKeys in constructor.
 *  we walk throught the js files AST
 *      if any string literal in that AST is in jsResourceI18nKeys then  we consider that string as I18n key
 *  after the walk of AST we get some I18n keys
 *  then we make it as I18nDependency.
 */

class I18nKeysIdentifer {
  constructor({
    jsResourceI18nKeys
  }, {
    I18nDependency,
    I18nModule
  }) {
    this.jsResourceI18nKeys = jsResourceI18nKeys;
    this.I18nDependency = I18nDependency;
    this.I18nModule = I18nModule;
    this.modulesI18nKeysMap = {};
  }

  defineConfigarationForI18nDependency(compilation) {
    const {
      I18nModule,
      I18nDependency
    } = this;

    class I18nModuleFactory {
      // eslint-disable-next-line class-methods-use-this
      create({
        dependencies: [dependency]
      }, callback) {
        callback(undefined, new I18nModule(dependency));
      }

    }

    compilation.dependencyFactories.set(I18nDependency, new I18nModuleFactory());

    class I18nDependencyTemplate {
      // eslint-disable-next-line class-methods-use-this
      apply() {}

    }

    compilation.dependencyTemplates.set(I18nDependency, new I18nDependencyTemplate());
  }

  addI18nDependency(module, i18nKeys) {
    const identifier = `i18n ${module.resource}`;
    const dep = new this.I18nDependency({
      identifier,
      content: JSON.stringify(i18nKeys),
      i18nKeys
    }, module.context, 0);
    module.addDependency(dep);
  }

  apply(compiler) {
    // const { splitChunks } = compiler.options.optimization;
    // if (splitChunks) {
    //   if (splitChunks.defaultSizeTypes.includes('...')) {
    //     splitChunks.defaultSizeTypes.push(MODULE_TYPE);
    //   }
    // }
    compiler.hooks.thisCompilation.tap(pluginName, compilation => {
      // this below  hook was tapped for  we use I18nDependency
      // so we must define module factory for I18nDependency
      // and we must define how it import statement look like I18nDependencyTemplate
      this.defineConfigarationForI18nDependency(compilation);
    });
    compiler.hooks.normalModuleFactory.tap(pluginName, factory => {
      // handler for parser
      const handler = parser => {
        parser.hooks.program.tap(pluginName, (ast, commmets) => {
          const {
            module
          } = parser.state; //

          if (!(module && /\.jsx?$/.test(module.resource))) {
            return;
          } // i18n grep proper contract regex


          let i18nKeys = (0, _utils.collectI18nKeysfromAST)(ast, this.jsResourceI18nKeys);
          i18nKeys = i18nKeys.concat( // i18n grep proper contract regex
          (0, _utils.collectI18nKeysfromComments)(commmets, this.jsResourceI18nKeys));

          if (i18nKeys.length) {
            // console.log(
            //   'i18nKeys.length',
            //   module.resource,
            //   i18nKeys.length < 5 ? i18nKeys : i18nKeys.length
            // );
            this.modulesI18nKeysMap[module.resource] = i18nKeys;
            this.addI18nDependency(module, i18nKeys);
          }
        });
      }; // this below  hook was tapped for collect I18n Key from files and add as Deppenensy
      // const factory = params.normalModuleFactory;


      factory.hooks.parser.for('javascript/auto').tap(pluginName, handler);
      factory.hooks.parser.for('javascript/dynamic').tap(pluginName, handler);
    });
  }

} // I18nKeysIdentifer.isChunkHasI18n = function (chunk) {
//   // eslint-disable-next-line no-restricted-syntax
//   for (const module of chunk.modulesIterable) {
//     // eslint-disable-next-line no-restricted-syntax
//     for (const dep of module.dependencies) {
//       if (dep instanceof I18nDependency) {
//         return true;
//       }
//     }
//   }
//   return false;
// };


exports.default = I18nKeysIdentifer;