"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _a, _CLIPlugin_progressStates;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CLIPlugin = void 0;
class CLIPlugin {
    constructor(options) {
        this.options = options;
    }
    async setupBundleAnalyzerPlugin(compiler) {
        // eslint-disable-next-line node/no-extraneous-require,@typescript-eslint/no-var-requires
        const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
        const bundleAnalyzerPlugin = Boolean(compiler.options.plugins.find((plugin) => plugin instanceof BundleAnalyzerPlugin));
        if (!bundleAnalyzerPlugin) {
            new BundleAnalyzerPlugin().apply(compiler);
        }
    }
    setupProgressPlugin(compiler) {
        const { ProgressPlugin } = compiler.webpack || require("webpack");
        const progressPlugin = Boolean(compiler.options.plugins.find((plugin) => plugin instanceof ProgressPlugin));
        if (progressPlugin) {
            return;
        }
        const isProfile = this.options.progress === "profile";
        const options = {
            profile: isProfile,
        };
        if (this.options.isMultiCompiler && ProgressPlugin.createDefaultHandler) {
            const handler = ProgressPlugin.createDefaultHandler(isProfile, compiler.getInfrastructureLogger("webpack.Progress"));
            const idx = __classPrivateFieldGet(CLIPlugin, _a, "f", _CLIPlugin_progressStates).length;
            __classPrivateFieldGet(CLIPlugin, _a, "f", _CLIPlugin_progressStates)[idx] = [0];
            options.handler = (p, msg, ...args) => {
                __classPrivateFieldGet(CLIPlugin, _a, "f", _CLIPlugin_progressStates)[idx] = [p, msg, ...args];
                let sum = 0;
                for (const [p] of __classPrivateFieldGet(CLIPlugin, _a, "f", _CLIPlugin_progressStates)) {
                    sum += p;
                }
                handler(sum / __classPrivateFieldGet(CLIPlugin, _a, "f", _CLIPlugin_progressStates).length, `[${compiler.name ? compiler.name : idx}] ${msg}`, ...args);
            };
        }
        new ProgressPlugin(options).apply(compiler);
    }
    setupHelpfulOutput(compiler) {
        const pluginName = "webpack-cli";
        const getCompilationName = () => (compiler.name ? `'${compiler.name}'` : "");
        const logCompilation = (message) => {
            if (process.env.WEBPACK_CLI_START_FINISH_FORCE_LOG) {
                process.stderr.write(message);
            }
            else {
                this.logger.log(message);
            }
        };
        const { configPath } = this.options;
        compiler.hooks.run.tap(pluginName, () => {
            const name = getCompilationName();
            logCompilation(`Compiler${name ? ` ${name}` : ""} starting... `);
            if (configPath) {
                this.logger.log(`Compiler${name ? ` ${name}` : ""} is using config: ${configPath
                    .map((path) => `'${path}'`)
                    .join(", ")}`);
            }
        });
        compiler.hooks.watchRun.tap(pluginName, (compiler) => {
            const { bail, watch } = compiler.options;
            if (bail && watch) {
                this.logger.warn('You are using "bail" with "watch". "bail" will still exit webpack when the first error is found.');
            }
            const name = getCompilationName();
            logCompilation(`Compiler${name ? ` ${name}` : ""} starting... `);
            if (configPath) {
                this.logger.log(`Compiler${name ? ` ${name}` : ""} is using config: '${configPath}'`);
            }
        });
        compiler.hooks.invalid.tap(pluginName, (filename, changeTime) => {
            const date = new Date(changeTime);
            this.logger.log(`File '${filename}' was modified`);
            this.logger.log(`Changed time is ${date} (timestamp is ${changeTime})`);
        });
        (compiler.webpack ? compiler.hooks.afterDone : compiler.hooks.done).tap(pluginName, () => {
            const name = getCompilationName();
            logCompilation(`Compiler${name ? ` ${name}` : ""} finished`);
            process.nextTick(() => {
                if (compiler.watchMode) {
                    this.logger.log(`Compiler${name ? `${name}` : ""} is watching files for updates...`);
                }
            });
        });
    }
    apply(compiler) {
        this.logger = compiler.getInfrastructureLogger("webpack-cli");
        if (this.options.progress) {
            this.setupProgressPlugin(compiler);
        }
        if (this.options.analyze) {
            this.setupBundleAnalyzerPlugin(compiler);
        }
        this.setupHelpfulOutput(compiler);
    }
}
exports.CLIPlugin = CLIPlugin;
_a = CLIPlugin;
_CLIPlugin_progressStates = { value: [] };
module.exports = CLIPlugin;
