"use strict";
const path = require("path");
const utils = require("./utils");
const webpack = require("webpack");
const config = require("../config");
const merge = require("webpack-merge");
const baseWebpackConfig = require("./webpack.base.conf");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const FriendlyErrorsPlugin = require("friendly-errors-webpack-plugin");
const portfinder = require("portfinder");
const ip = require("ip");
const devConfig = require("../config/dev.env");
const uiPackageJson = require("ui-component-v4/package");
let commonPackageJson;
if (devConfig.IS_BASE_PACKAGE === true + "") {
    commonPackageJson = require("ui-jz-v4-common/package");
}

function resolve(dir) {
    return path.join(__dirname, "..", dir);
}

const HOST = process.env.HOST;
const PORT = process.env.PORT && Number(process.env.PORT);

const devWebpackConfig = merge(baseWebpackConfig, {
    mode: "development",
    module: {
        rules: utils.styleLoaders({
            sourceMap: config.dev.cssSourceMap,
            usePostCSS: true
        })
    },
    // cheap-module-eval-source-map is faster for development
    devtool: config.dev.devtool,

    // these devServer options should be customized in /config/index.js
    devServer: {
        clientLogLevel: "warning",
        historyApiFallback: true,
        disableHostCheck: true,
        hot: true,
        compress: true,
        host: HOST || config.dev.host,
        port: PORT || config.dev.port,
        open: config.dev.autoOpenBrowser,
        overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false,
        publicPath: config.dev.assetsPublicPath,
        proxy: config.dev.proxyTable,
        quiet: true, // necessary for FriendlyErrorsPlugin
        watchOptions: {
            poll: config.dev.poll
        }
    },
    plugins: [
        new webpack.DefinePlugin({
            "process.env": require("../config/dev.env")
        }),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
        new webpack.NoEmitOnErrorsPlugin(),
        // https://github.com/ampedandwired/html-webpack-plugin
        new HtmlWebpackPlugin({
            filename: "index.html",
            template: "index.html",
            inject: true,
            favicon: resolve("favicon.ico"),
            title: "ui-jz-v4",
            templateParameters: {
                BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
            }
        }),
        // copy custom static assets
        new CopyWebpackPlugin([
            {
                from: path.resolve(__dirname, "../static"),
                to: config.dev.assetsSubDirectory,
                ignore: [".*"]
            }
        ])
    ]
});

module.exports = new Promise((resolve, reject) => {
    portfinder.basePort = process.env.PORT || config.dev.port;
    portfinder.getPort((err, port) => {
        if (err) {
            reject(err);
        } else {
            // publish the new Port, necessary for e2e tests
            process.env.PORT = port;
            // add port to devServer config
            devWebpackConfig.devServer.port = port;

            let messages = [
                `   App running at:`,
                `   - Local:   http://localhost:${port}`,
                `   - Network: http://${ip.address()}:${port}`,
                `   ui-component-v4 version is ${uiPackageJson.version}`
            ];

            if (devConfig.IS_BASE_PACKAGE === true + "") {
                messages.push(`   ui-jz-v4 version is ${commonPackageJson.version}`);
            }

            if (devConfig.PROXY_TABLE) {
                const address = [`   Back end access address:`]
                const proxy = JSON.parse(devConfig.PROXY_TABLE)
                for (let key in proxy) {
                    address.push(`          proxy: ${key}, target: ${proxy[key].target}`)
                }
                messages.push(address.join('\n'))
            }

            // Add FriendlyErrorsPlugin
            devWebpackConfig.plugins.push(
                new FriendlyErrorsPlugin({
                    compilationSuccessInfo: {
                        messages: messages
                    },
                    onErrors: config.dev.notifyOnErrors ? utils.createNotifierCallback() : undefined
                })
            );

            resolve(devWebpackConfig);
        }
    });
});
