"use strict";

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

var _webpack = require("webpack");

const pluginName = 'RuntimeResourceCleanupPlugin';

class RuntimeResourceCleanup {
  constructor({
    enable: scriptCleanUpEnabled,
    chunkLoadingGlobal,
    ...options
  }) {
    this.options = options;
    this.scriptCleanUpEnabled = scriptCleanUpEnabled;
    this.chunkLoadingGlobal = chunkLoadingGlobal;
  }

  apply(compiler) {
    compiler.hooks.compilation.tap(pluginName, compilation => {
      compilation.hooks.processAssets.tap({
        name: pluginName,
        stage: _webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS
      }, assets => {
        const runtimeFiles = Object.keys(assets).filter(assetName => /.+?runtime.*\.js$/.test(assetName));
        const searchString = 'chunkLoadingGlobal.forEach';

        function generateScriptCleanUpCode(attributes) {
          const [[attributeKey, attributeValue]] = Object.entries(attributes);
          const selectorForGettingResources = `[${attributeKey}="${attributeValue}"]`;
          return `
            document.querySelectorAll('${selectorForGettingResources}').forEach(resource => resource.remove());
            `;
        }

        function generateRunTimeObjectCleanupCode() {
          return `
                    Object.keys(__webpack_modules__).forEach(moduleKey => __webpack_modules__[moduleKey] = null);
                    Object.keys(__webpack_module_cache__).forEach(moduleCacheKey => __webpack_module_cache__[moduleCacheKey] = null);
                    __webpack_modules__ = null; 
                    __webpack_module_cache__ = null;
                    Object.keys(__webpack_require__).forEach(staticMethodsKey => __webpack_require__[staticMethodsKey] = null);
                    __webpack_require__ = null;
                    `;
        }

        function attachUninstallMethodToChunkGlobal() {
          const {
            chunkLoadingGlobal
          } = this;
          return `self['${chunkLoadingGlobal}'].unInstall = function() {
              ${generateRunTimeObjectCleanupCode()};
              ${this.scriptCleanUpEnabled ? generateScriptCleanUpCode(this.options.attributes) : ''}
            }`;
        }

        runtimeFiles.forEach(runtTimeFile => {
          const runTimeSource = assets[runtTimeFile].source();
          const newRunTimeCode = runTimeSource.replace(searchString, `${attachUninstallMethodToChunkGlobal.call(this)};${searchString}`);
          const newRunTimeResource = new compiler.webpack.sources.RawSource(newRunTimeCode);
          compilation.updateAsset(runtTimeFile, newRunTimeResource);
        });
      });
    });
  }

}

exports.default = RuntimeResourceCleanup;