const chalk = require("chalk");
const fs = require("fs");
const Logger = require("../Logger");
const webpack = require("webpack");


class WebpackRunner
{
    /**
     * Constructs a new runner
     * @param {KabaBuildConfig} buildConfig
     * @param {CliConfig} cliConfig
     */
    constructor (buildConfig, cliConfig)
    {
        /**
         * @private
         * @type {KabaBuildConfig}
         */
        this.buildConfig = buildConfig;

        /**
         * @private
         * @type {CliConfig}
         */
        this.cliConfig = cliConfig;

        /**
         * @private
         * @type {Logger}
         */
        this.logger = new Logger(chalk.bgCyan.black(" webpack "));
    }


    /**
     * Runs the actual runner
     *
     * @return {Promise<boolean>} whether the build was successful and error-free
     */
    async run ()
    {
        if (Object.keys(this.buildConfig.entry).length === 0)
        {
            return true;
        }

        return new Promise(
            (resolve) =>
            {
                this.logger.log("Launching webpack...");
                const start = process.hrtime();

                webpack(
                    this.buildConfig.js.webpack,
                    /**
                     * @param {Error|null} error
                     * @param {webpack.stats} stats
                     * @return {void}
                     */
                    (error, stats) =>
                    {
                        if (error)
                        {
                            this.logger.logError("webpack error", error);
                            this.logger.logWithDuration("webpack finished", process.hrtime(start));
                            return resolve(false);
                        }

                        // log webpack output
                        console.log(stats.toString({
                            colors: true,
                        }));
                        console.log("");

                        // write dependencies file
                        fs.writeFileSync(
                            path.join(this.buildConfig.output.path, `${this.buildConfig.js.javaScriptDependenciesFileName}.json`),
                            JSON.stringify(this.fetchEntryDependencies(stats)),
                            "utf-8"
                        );

                        this.logger.logWithDuration("webpack finished", process.hrtime(start));

                        if (stats.hasErrors())
                        {
                            return resolve(false);
                        }

                        resolve(true);
                    }
                );
            }
        );
    }


    /**
     * Fetches all entry dependencies
     *
     * @private
     * @param {Stats} stats
     * @return {Object<string, string[]>}
     */
    fetchEntryDependencies (stats)
    {
        const entrypoints = {};

        for (const mapEntry of stats.compilation.entrypoints.entries())
        {
            const entry = mapEntry[1];
            entrypoints[entry.name] = entry.chunks.reduce(
                (files, chunk) => {
                    return files.concat(chunk.files);
                },
                []
            );
        }

        return entrypoints;
    }
}

module.exports = WebpackRunner;

@@ -84,24 +84,54 @@
 ./Logger%22);%0A
+const path = require(%22path%22);%0A
 const webpac
@@ -464,32 +464,164 @@
 = buildConfig;%0A%0A
+        /**%0A         * @private%0A         * @type %7Bwebpack.config%7D%0A         */%0A        this.webpackConfig = buildConfig.js.webpack;%0A%0A
         /**%0A    
@@ -1042,29 +1042,31 @@
 t.keys(this.
-build
+webpack
 Config.entry
@@ -1350,38 +1350,29 @@
    this.
-buildConfig.js.
 webpack
+Config
 ,%0A      
@@ -2216,297 +2216,40 @@
     
-fs.writeFileSync(%0A                            path.join(this.buildConfig.output.path, %60$%7Bthis.buildConfig.js.javaScriptDependenciesFileName%7D.json%60),%0A                            JSON.stringify(this.fetchEntryDependencies(stats)),%0A                            %22utf-8%22%0A                        
+this.writeDependenciesFile(stats
 );%0A%0A
@@ -2628,19 +2628,18 @@
   * 
-Fetches all
+Writes the
  ent
@@ -2653,16 +2653,21 @@
 ndencies
+ file
 %0A     *%0A
@@ -2720,66 +2720,19 @@
    *
- @return %7BObject%3Cstring, string%5B%5D%3E%7D%0A     */%0A    fetchEntry
+/%0A    write
 Depe
@@ -2739,16 +2739,20 @@
 ndencies
+File
  (stats)
@@ -3137,26 +3137,337 @@
     
-return entrypoints
+const fileName = %60$%7Bthis.buildConfig.js.javaScriptDependenciesFileName%7D.json%60;%0A        fs.writeFileSync(%0A            path.join(this.webpackConfig.output.path, fileName),%0A            JSON.stringify(entrypoints),%0A            %22utf-8%22%0A        );%0A        this.logger.log(chalk%60Entrypoint dependencies written to %7Byellow $%7BfileName%7D%7D%60)
 ;%0A  

Improve webpack runner + logging