"use strict";

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

var _fs = _interopRequireDefault(require("fs"));

var _path = _interopRequireDefault(require("path"));

var _stream = require("stream");

var _objectManipulation = require("../../utils/object-manipulation");

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

const pluginName = 'BundleIntegrityReportPlugin';

class BundleIntegrityReport {
  constructor({
    options,
    excludeKeysInReport,
    fileName
  }) {
    this.excludeKeysInStat = excludeKeysInReport;
    this.statsFileName = fileName;
    this.statsOptions = options;
  }

  apply(compiler) {
    compiler.hooks.done.tapAsync(pluginName, (stats, callback) => {
      const statsJson = (0, _objectManipulation.removeKeysFromObject)(stats.toJson(this.statsOptions), this.excludeKeysInStat);
      this.emitStats(statsJson).on('end', () => {
        callback();
      }).on('error', e => {
        callback(e);
      });
    });
  }

  writeStatsFileInAStream(statsObj) {
    const {
      outputPath
    } = statsObj;

    const ouputFileName = _path.default.join(outputPath, this.statsFileName);

    return this.createReadStream(statsObj).pipe(_fs.default.createWriteStream(ouputFileName));
  }

  createReadStream(statsObj) {
    const excludeKeys = this.excludeKeysInStat;
    return new _stream.Readable({
      read() {
        let isDone = false;
        const objToStringGen = (0, _objectManipulation.convertObjectToStringGen)(statsObj, excludeKeys);

        while (!isDone) {
          const {
            done,
            value
          } = objToStringGen.next();

          if (done) {
            isDone = true;
            this.push(null);
          } else {
            this.push(value);
          }
        }
      }

    });
  }

  emitStats(statsJson) {
    return this.writeStatsFileInAStream(statsJson);
  }

}

exports.BundleIntegrityReport = BundleIntegrityReport;