// Importing modules
require('dotenv').config();
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const git = require('git-rev-sync');
const packageJson = require('./package.json');

module.exports = (options) => {
    // Checking if we are trying to build for Production Env
    const isProd = options.prod;
    try {
        gitTag = git.tag();
    } catch (e) {}
    const defineData = {
        GIT_TAG: `'${gitTag}'`,
        PACKAGE_VERSION: `'${packageJson.version}'`,
        HYDRAJS_VERSION: `'${packageJson.dependencies.hydrajs}'`
    };
    // Config which will be used by webpack to build our bundle
    /** Common Config */
    const config = {
        // Telling webpack that src/index is from where our app starts
        entry: {
            polyfill: path.resolve(__dirname, 'src', 'polyfill'),
            index: path.resolve(__dirname, 'src', 'index')
        },
        // After bundling what should be the output and what should be the location for the same
        output: {
            filename: '[name].[hash:8].js',
            // this is used when we are using code splitting with dynamic import
            chunkFilename: '[name].[chunkhash:8].chunk.js',
            // Output location
            path: path.resolve(__dirname, 'dist', 'assets')
        },
        // This is telling webpack what all extension it needs to build
        resolve: {
            extensions: ['.ts', '.tsx', '.js'],
            symlinks: false
        },
        module: {
            rules: [
                {
                    // test: resolve(__dirname, '..', 'node_modules/ccxt'),
                    test: /\.(js)$/,
                    loader: 'babel-loader',
                    options: {
                        babelrc: false,
                        cacheDirectory: false,
                        presets: ["@babel/preset-env"],
                        plugins: [require("@babel/plugin-transform-arrow-functions")]
                    }
                },
                // Here we are telling webpack to use ts-loader to compile our ts
                {
                    test: /\.(ts|tsx)$/,
                    loader: 'ts-loader',
                    options: {
                        configFile: isProd ? 'tsconfig.json' : 'tsconfig-dev.json'
                    },
                    exclude: /node_modules/
                },

                {
                    test: /\.css$/,
                    use: [
                        {
                            loader: MiniCssExtractPlugin.loader,
                            options: {
                                // you can specify a publicPath here
                                // by default it use publicPath in webpackOptions.output
                                publicPath: '../'
                            }
                        },
                        "css-loader"
                    ]
                    // exclude: /node_modules/
                },
                // {
                //     test: /\.scss$/,
                //     use: [
                //         {
                //             loader: MiniCssExtractPlugin.loader,
                //             options: {
                //                 // you can specify a publicPath here
                //                 // by default it use publicPath in webpackOptions.output
                //                 publicPath: '../'
                //             }
                //         },
                //         "css-loader", 'sass-loader'
                //     ]
                // },
                {
                    test: /\.s(a|c)ss$/,
                    exclude: /\.module.(s(a|c)ss)$/,
                    loader: [
                        !isProd ? 'style-loader' : MiniCssExtractPlugin.loader, 'css-loader',
                        {
                            loader: 'sass-loader',
                            options: {
                                sourceMap: !isProd
                            }
                        }
                    ]
                },
                {
                    test: /\.(jpe?g|gif|svg)/i,
                    use: [
                      'file-loader?hash=sha512&digest=hex&name=[hash].[ext]',
                      {
                        loader: 'image-webpack-loader',
                        query: {
                          mozjpeg: {
                            progressive: true
                          },
                          pngquant: {
                            quality: '65-90',
                            speed: 4
                          },
                          optipnq: {
                            optimizationLevel: 7
                          },
                          gifsicle: {
                            interlaced: false,
                            optimizationLevel: 3
                          }
                        }
                      }
                    ]
                  },
                  {
                    test: /\.(png)/,
                    use: ['file-loader?hash=sha512&digest=hex&name=[hash].[ext]']
                  },
                  {
                    test: /\.(woff|woff2)/,
                    use: ['url-loader']
                  },
                  {
                    test: /\.(ttf|eot)/,
                    use: ['file-loader']
                  },
                {
                    test: /\.po$/,
                    use: ['i18next-po-loader']
                }
            ]
        },
        plugins: [
            new webpack.DefinePlugin(defineData),
            new MiniCssExtractPlugin({
                filename: '[name].css'
            })
        ],
        optimization: {
            splitChunks: {
                cacheGroups: {
                    default: false,
                    vendors: false,

                    // vendor chunk
                    vendor: {
                        // name of the chunk
                        name: 'vendor',
                        // sync + async chunks
                        chunks: 'all',
                        // import file path containing node_modules
                        test: /node_modules/,
                        // priority
                        priority: 20
                    },

                    // common chunk
                    common: {
                        name: 'common',
                        minChunks: 2,
                        chunks: 'all',
                        priority: 10,
                        reuseExistingChunk: true,
                        enforce: true
                    }
                }
            }
        }
    };
    /** Prod Config */
    if (isProd) {
        config.mode = 'production';

        config.plugins.push(
            // Terser plugin is ued to generate ugly js
            new TerserPlugin({
                parallel: true,
                sourceMap: true,
                terserOptions: {
                    parse: {
                        ecma: 8
                    },
                    ie8: false,
                    ecma: 5,
                    mangle: {
                        keep_fnames: true
                    },
                    output: {
                        comments: false,
                        beautify: false
                    },
                    compress: {
                        warnings: false,
                        conditionals: true,
                        unused: true,
                        comparisons: true,
                        sequences: true,
                        dead_code: true,
                        evaluate: true,
                        if_return: true,
                        join_vars: true
                    },
                    warnings: false
                }
            }),
            // This is used to append our js into html and at the same time minify it
            new HtmlWebpackPlugin({
                template: path.resolve(__dirname, 'public', 'index.html'),
                inject: 'body',
                hash: true,
                chunksSortMode: 'dependency',
                minify: {
                    removeComments: false,
                    collapseWhitespace: true,
                    removeRedundantAttributes: true,
                    useShortDoctype: true,
                    removeEmptyAttributes: true,
                    removeStyleLinkTypeAttributes: true,
                    keepClosingSlash: true,
                    minifyJS: true,
                    minifyCSS: true,
                    minifyURLs: true,
                }
            })
        );

        // config.module.rules.push(
        //     {
        //         test: /\.css$/,
        //         exclude: /node_modules/,
        //         use: [MiniCssExtractPlugin.loader, 'style-loader', 'css-loader']
        //     }
        // );

        config.devtool = options.devTool;
    } else {
        /** Dev config */
        config.mode = 'development';
        config.plugins.push(
            new HtmlWebpackPlugin({
                template: path.resolve(__dirname, 'public', 'index.html'),
                inject: 'body',
                hash: true
            })
        );
        // config.module.rules.push({
        //     test: /\.s?css$/,
        //     // exclude: /node_modules/,
        //     use: ['style-loader', 'css-loader']
        // });
        config.devtool = options.devTool;
    }

    config.devServer = {
        compress: true,
        clientLogLevel: 'info',
        historyApiFallback: true,
        host: process.env.HOST,
        port: process.env.PORT,
        publicPath: process.env.PUBLIC_PATH,
        overlay: true,
        disableHostCheck: true
    };

    return config;
};
