const fs = require('fs');
const path = require('path');

const root = path.resolve(__dirname, '..');
const files = [
  path.join(root, 'node_modules/webpackbar/dist/index.cjs'),
  path.join(root, 'node_modules/webpackbar/dist/index.mjs')
];

const oldApplyPatch = `compiler.webpackbar = this;
    const webpackbarOptions = this.options;
    this.options = { activeModules: true };
    try {
      super.apply(compiler);
    } finally {
      this.options = webpackbarOptions;
    }`;
const applyMarker = `compiler.webpackbar = this;
    super.apply(compiler);`;

const constructorMarker = `this.options = Object.assign({}, DEFAULTS, options);
    this.handler = (percent, message, ...details) => {`;
const constructorReplacement = `this.webpackbarOptions = Object.assign({}, DEFAULTS, options);
    this.options = { activeModules: true };
    this.handler = (percent, message, ...details) => {`;

const replacements = [
  ['this.options.reporters', 'this.webpackbarOptions.reporters'],
  ['this.options.reporter', 'this.webpackbarOptions.reporter'],
  ['this.options[reporter]', 'this.webpackbarOptions[reporter]'],
  ['globalStates[this.options.name]', 'globalStates[this.webpackbarOptions.name]'],
  ['this.states[this.options.name]', 'this.states[this.webpackbarOptions.name]'],
  ['color: this.options.color', 'color: this.webpackbarOptions.color'],
  ['name: startCase(this.options.name)', 'name: startCase(this.webpackbarOptions.name)']
];

let patched = 0;
for (const file of files) {
  if (!fs.existsSync(file)) {
    continue;
  }
  let source = fs.readFileSync(file, 'utf8');
  let next = source;

  if (next.includes(oldApplyPatch)) {
    next = next.replace(oldApplyPatch, applyMarker);
  }

  if (next.includes(constructorMarker)) {
    next = next.replace(constructorMarker, constructorReplacement);
  } else if (!next.includes(constructorReplacement)) {
    throw new Error(`webpackbar constructor patch marker not found: ${file}`);
  }

  for (const [from, to] of replacements) {
    next = next.split(from).join(to);
  }

  if (!next.includes(constructorReplacement)) {
    throw new Error(`webpackbar progress patch failed: ${file}`);
  }
  if (next !== source) {
    fs.writeFileSync(file, next);
    patched += 1;
  }
}

if (patched > 0) {
  console.log(`Patched webpackbar ProgressPlugin compatibility in ${patched} file(s).`);
}
