"use strict";

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

var _htmlWebpackPlugin = _interopRequireDefault(require("html-webpack-plugin"));

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

const pluginName = 'CustomScriptLoadingStrategyPlugin';

class CustomScriptLoadingStrategyPlugin {
  constructor({
    scriptLoadingStategey
  } = {}) {
    this.scriptLoadingStrategy = scriptLoadingStategey;
    this.tagNamesToMatch = ['script'];
  }

  getFileNameFromTagSrc(src) {
    const fileNameArr = src.split('/');
    return fileNameArr[fileNameArr.length - 1];
  }

  addAttributestToTag(tag, attributes) {
    tag.attributes = Object.assign({}, tag.attributes, attributes);
  }

  matchFileName(tag, fileName) {
    return fileName.test(this.getFileNameFromTagSrc(tag.attributes.src));
  }

  blockingStrategy(tag) {
    delete tag.attributes.defer;
    delete tag.attributes.async;
  }

  deferStrategy(tag) {
    delete tag.attributes.async;
  }

  asyncStrategy(tag) {
    delete tag.attributes.defer;
  }

  moduleStrategy(tag) {
    this.deferStrategy(tag);
  }

  matchStrategy(scriptLoadingStrategy, tag) {
    if (scriptLoadingStrategy === 'blocking') {
      this.blockingStrategy(tag);
    }

    if (scriptLoadingStrategy === 'defer') {
      this.deferStrategy(tag);
    }

    if (scriptLoadingStrategy === 'async') {
      this.asyncStrategy(tag);
    }

    if (scriptLoadingStrategy === 'module') {
      this.moduleStrategy(tag);
    }
  }

  matchAndApplyCustomLoadingStrategyToScripts(tags) {
    Object.keys(this.scriptLoadingStrategy).forEach(scriptLoadingStrategy => {
      const filesToMatch = this.scriptLoadingStrategy[scriptLoadingStrategy];
      tags.forEach(tag => {
        if (this.tagNamesToMatch.includes(tag.tagName) && tag.attributes.src) {
          const isFileMatch = filesToMatch.some(fileName => this.matchFileName(tag, fileName));

          if (isFileMatch) {
            this.matchStrategy(scriptLoadingStrategy, tag);
            this.addAttributestToTag(tag, {
              [scriptLoadingStrategy]: true
            });
          }
        } // filesToMatch.forEach(fileName => {
        //   if (!this.matchFileName(tag, fileName)) {
        //     return;
        //   }
        //   this.matchStrategy(scriptLoadingStrategy, tag);
        //   this.addAttributestToTag(tag, fileName, {
        //     [scriptLoadingStrategy]: true
        //   });
        // });

      });
    });
  }

  apply(compiler) {
    compiler.hooks.compilation.tap(pluginName, compilation => {
      _htmlWebpackPlugin.default.getHooks(compilation).alterAssetTagGroups.tapAsync(pluginName, (data, callback) => {
        const tags = [...data.bodyTags, ...data.headTags];
        this.matchAndApplyCustomLoadingStrategyToScripts(tags);
        callback(null, data);
      });
    });
  }

}

exports.default = CustomScriptLoadingStrategyPlugin;