const { MergeHelper } = require("./webpack-helpers");
const PhpSerializer = require("./php-serializer");
const { ConfigLoader } = require("./webpack-helpers");
const fs = require("fs");
const path = require("path");

class ConfigBuilderPlugin {
  constructor(opts) {
    this.chunkName = opts && opts.chunkName ? opts.chunkName : "config";
    this.phpConstName = opts && opts.phpConstName ? opts.phpConstName : "INOBY_THEME_CONFIG";
  }

  apply(compiler) {
    let files = compiler.options.entry[this.chunkName].import;

    compiler.hooks.emit.tapAsync("config-builder", (compilation, callback) => {
      let configChunk = null;
      compilation.chunks.forEach((chunk) => {
        if (chunk.name == this.chunkName) {
          configChunk = chunk;
        }
      });
      let err = null;
      // wont let you fall
      try {
        if (configChunk) {
          // remove config assets
          configChunk.files.forEach((file) => delete compilation.assets[file]);
          compilation.chunks.delete(configChunk);

          // build config
          let buildDir = compiler.options.output.path;
          let config = this.build_config(files);
          this.write_config(config, buildDir, this.chunkName);
        }
      } catch (error) {
        err = error;
        console.error("CONFIG BUILDER EXCEPTION:", err);
      }
      callback(err);
    });
  }

  build_config(files) {
    const configs = ConfigLoader.load(files);
    return MergeHelper.merge(configs);
  }

  write_config(config, dir, file_name) {
    let file = path.resolve(dir, file_name + ".php");
    let content = "<?php " + PhpSerializer.serialize(config, this.phpConstName);
    fs.mkdirSync(dir, { recursive: true });
    fs.writeFileSync(file, content);
  }
}

module.exports = ConfigBuilderPlugin;
