/* eslint no-console: 0 */

'use strict';

const path = require('path');
const webpack = require('webpack');
const fs = require('fs');

const { version } = require('../package.json');

function getConfig(mode, dirname) {
    try {
        const BUILD_DIR = path.resolve(dirname, 'public');
        const APP_DIR = path.resolve(dirname, 'src');

        const sassVariables = path.resolve(dirname, 'src/Custom/Variables.scss').replace(/\\/g, '/');
        let sassVariablesFileExists = false;
        try {
            sassVariablesFileExists = fs.statSync(sassVariables).isFile();
        } catch (e) {
            console.log('No custom sass variables found. Place them at ' + sassVariables + ' if needed.');
        }

        const commonConfig = {
            context: APP_DIR,
            entry: ['@babel/polyfill', 'url-search-params-polyfill', APP_DIR],
            output: {
                path: BUILD_DIR,
                filename: 'bundle.js',
                publicPath: '/',
            },
            resolve: {
                extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'],
                fallback: { path: require.resolve('path-browserify') },
            },
        };

        const commonRules = [
            {
                test: /\.[jt]sx?$/,
                loader: 'babel-loader',
                include: [path.resolve('src')],
                options: {
                    envName: mode === 'dev' ? 'development' : 'production',
                },
            },
            {
                test: /\.(png|jpg|gif)$/,
                loader: 'url-loader',
                options: {
                    limit: 8192,
                    name: '[name]_[hash].[ext]',
                    outputPath: 'images/',
                },
            },
            {
                test: /\.svg$/,
                include: [path.resolve(__dirname, 'src/Resouces/Images')],
                loader: 'url-loader',
                options: {
                    limit: 8192,
                    name: '[name]_[hash].[ext]',
                    outputPath: 'images/',
                },
            },
            {
                test: /\.(ttf|svg|woff|woff2|eot|otf)$/,
                loader: 'url-loader',
                options: {
                    limit: 8192,
                    name: '[name]_[hash].[ext]',
                    outputPath: 'fonts/',
                    esModule: false,
                },
            },
        ];

        switch (mode) {
            case 'dev': {
                const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

                const env = new webpack.DefinePlugin({
                    'process.env.FRONTENDGUI_VERSION': JSON.stringify(version),
                });

                return {
                    ...commonConfig,
                    mode: 'development',
                    cache: true,
                    devtool: 'eval-cheap-module-source-map',
                    devServer: {
                        client: { overlay: false },
                        hot: 'only',
                        static: {
                            directory: BUILD_DIR,
                            publicPath: '/',
                        },
                        devMiddleware: {
                            publicPath: '/',
                        },
                        historyApiFallback: {
                            disableDotRule: true,
                        },
                    },
                    module: {
                        rules: [
                            {
                                test: /\.s?css$/,
                                use: [
                                    {
                                        loader: 'style-loader', // creates style nodes from JS strings
                                    },
                                    {
                                        loader: 'css-loader', // translates CSS into CommonJS
                                    },
                                    {
                                        loader: 'resolve-url-loader', // resolving urls in stylesheets
                                    },
                                    {
                                        loader: 'sass-loader', // compiles Sass to CSS
                                        options: {
                                            sourceMap: true,
                                            sassOptions: {
                                                includePaths: ['src'],
                                            },
                                            additionalData: sassVariablesFileExists
                                                ? `@import '${sassVariables}';\n`
                                                : '',
                                        },
                                    },
                                ],
                            },
                        ].concat(commonRules),
                    },
                    externals: {
                        cheerio: 'window',
                        'react/addons': true,
                        'react/lib/ExecutionEnvironment': true,
                        'react/lib/ReactContext': true,
                    },
                    plugins: [env, new ReactRefreshPlugin()],
                    resolve: Object.assign({}, commonConfig.resolve, {
                        ...commonConfig.resolve,
                        alias: {
                            ...commonConfig.resolve.alias,
                        },
                    }),
                    optimization: {
                        moduleIds: 'named',
                    },
                };
            }

            case 'prod': {
                const TerserPlugin = require('terser-webpack-plugin');
                const MiniCssExtractPlugin = require('mini-css-extract-plugin');

                const env = new webpack.DefinePlugin({
                    'process.env.NODE_ENV': JSON.stringify('production'),
                    'process.env.FRONTENDGUI_VERSION': JSON.stringify(version),
                });

                const extractSass = new MiniCssExtractPlugin({
                    filename: 'bundle.css',
                });

                const minimizer = new TerserPlugin({
                    parallel: true,
                    terserOptions: {
                        output: {
                            comments: false,
                        },
                    },
                });

                return {
                    ...commonConfig,
                    mode: 'production',
                    devtool: 'source-map',
                    devServer: {
                        hot: false,
                    },
                    module: {
                        rules: [
                            {
                                test: /\.s?css$/,
                                use: [
                                    MiniCssExtractPlugin.loader,
                                    {
                                        loader: 'css-loader',
                                        options: {
                                            sourceMap: false,
                                        },
                                    },
                                    {
                                        loader: 'resolve-url-loader', // resolving urls in stylesheets
                                    },
                                    {
                                        loader: 'sass-loader',
                                        options: {
                                            sourceMap: true,
                                            sassOptions: {
                                                includePaths: ['src'],
                                            },
                                            additionalData: sassVariablesFileExists
                                                ? `@import '${sassVariables}';\n`
                                                : '',
                                        },
                                    },
                                ],
                            },
                        ].concat(commonRules),
                    },
                    plugins: [
                        env,
                        extractSass,
                        new webpack.IgnorePlugin({
                            resourceRegExp: /^\.\/locale$/,
                            contextRegExp: /moment$/,
                        }),
                    ],
                    optimization: {
                        minimizer: [minimizer],
                    },
                };
            }
        }
    } catch (e) {
        console.log(JSON.stringify(e));
        throw e;
    }
}

module.exports = {
    getConfig: getConfig,
    default: getConfig,
};
