"use strict";

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

var _webpack = require("webpack");

var _createHash = require("./createHash");

var _pathCreator = require("./pathCreator");

var _propertiesUtils = require("./utils/propertiesUtils");

var _LocaleChunkAssetsStore = require("./LocaleChunkAssetsStore");

/* eslint-disable no-restricted-syntax */
const pluginName = 'I18nFilesEmitPlugin';
const {
  RawSource
} = _webpack.sources;

class I18nFilesEmitPlugin {
  constructor(options) {
    this.options = options; // this.options = {
    //   locales: options.locales,
    //   chunkFilename: options.chunkFilename,
    //   filename: options.filename,
    //   allI18nObject: options.allI18nObject,
    //   jsonpFunc: options.jsonpFunc
    // };
  }

  apply(compiler) {
    compiler.hooks.thisCompilation.tap(pluginName, compilation => {
      // Get store for cache
      this.store = (0, _LocaleChunkAssetsStore.getLocaleChunkAssetsStore)(compilation);
      const i18nStore = this.store;
      compilation.hooks.beforeHash.tap(pluginName, () => {
        i18nStore.clear();
        this.createAndStoreFileContentForEveryChunkAndLocale(compilation);
      });
      compilation.hooks.chunkHash.tap(pluginName, (chunk, hash) => {
        this.updateChunkHashForEveryLocale(chunk, hash);
      });
      compilation.hooks.contentHash.tap(pluginName, chunk => {
        if (!i18nStore.isChunkHasI18n(chunk.id)) {
          return;
        }

        this.emitI18nFileForEveryLocale(chunk, compilation);
      });
    });
  }

  createAndStoreFileContentForEveryChunkAndLocale(compilation) {
    const {
      chunks
    } = compilation;
    const {
      locales
    } = this.options;
    const i18nStore = this.store;

    for (const chunk of chunks) {
      const i18nKeys = i18nStore.getI18nKeysForChunk(chunk);

      if (!i18nKeys.length) {
        // eslint-disable-next-line no-continue
        continue;
      }

      for (const locale of locales) {
        const content = this.getI18nChunkFileContent(i18nKeys, locale);
        i18nStore.storeData(chunk.id, locale, {
          content
        });
      }
    }
  }

  updateChunkHashForEveryLocale(chunk, hash) {
    const {
      locales
    } = this.options;
    const i18nStore = this.store;

    if (i18nStore.isChunkHasI18n(chunk.id)) {
      for (const loc of locales) {
        const content = i18nStore.getContent(chunk.id, loc);
        hash.update(content);
      }
    }
  }

  emitI18nFileForEveryLocale(chunk, compilation) {
    const i18nStore = this.store;
    const {
      locales,
      chunkFilename,
      filename
    } = this.options;
    const fileNameTemplate = chunk.canBeInitial() ? filename : chunkFilename; // const { chunks } = compilation;

    for (const locale of locales) {
      const content = i18nStore.getContent(chunk.id, locale);
      const contentHash = (0, _createHash.createHash)({
        outputOptions: compilation.outputOptions,
        content
      });
      const {
        filename
      } = I18nFilesEmitPlugin.createFilenameWithHash({
        compilation,
        contentHash,
        fileNameTemplate,
        chunk,
        locale
      });
      i18nStore.storeData(chunk.id, locale, {
        contentHash,
        filename
      });
      compilation.emitAsset(filename, new RawSource(content));
    }
  }

  static createFilenameWithHash({
    compilation,
    fileNameTemplate,
    chunk,
    locale,
    contentHash
  }) {
    const fileName = fileNameTemplate.replaceAll('[locale]', locale);
    const filename = (0, _pathCreator.pathCreator)(fileName, compilation, {
      hash: compilation.hash,
      chunkId: chunk.id,
      chunkHash: chunk.hash,
      contentHash
    });
    return {
      contentHash,
      filename
    };
  }

  getI18nContentForkeys(i18nKeys, locale) {
    const {
      allI18nObject
    } = this.options;
    const data = {};

    for (const key of i18nKeys) {
      data[key] = allI18nObject[locale][key];
    }

    return data;
  }

  getI18nChunkFileContent(i18nKeys, loc) {
    const {
      jsonpFunc
    } = this.options;
    const data = this.getI18nContentForkeys(i18nKeys, loc);
    return `${jsonpFunc}(${(0, _propertiesUtils.jsonToString)(data)})`;
  }

}

exports.I18nFilesEmitPlugin = I18nFilesEmitPlugin;