const path = require('path');
const glob = require('glob');
const webpack = require('webpack');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const VirtualModulePlugin = require('virtual-module-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackIncludeAssetsPlugin = require('html-webpack-include-assets-plugin');
const ROOT = process.cwd();
const SRC = path.join(ROOT, 'src');
const DIST = path.join(ROOT, 'dist');
const vueLoaderConfig = require('./vue-loader.conf');
const fs = require('fs');

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

// entries
let files = glob.sync(path.join(SRC, 'pages/*/index.vue'));
let entries = {};
files.forEach(f => {
    var name = /.*\/pages\/(.*)\/index.vue/.exec(f)[1];
    entries[name] = f.replace(/index.vue$/, 'index.js').replace(ROOT, '.'); // ./src...
});

// js entries
let entryCode = require('./page-entry.web');
let virtualEntries = [];
Object.keys(entries).forEach(name => {
    let path = entries[name];
    virtualEntries.push({
        moduleName: path,
        contents: entryCode
    });
});

// html entries
let htmlEntries = Object.keys(entries).map(name => {
    return {
        title: name,
        filename: name + '.html',
        template: path.join(__dirname, 'template.html'),
        chunks: [name]
    };
});

let blConfig = { isUni: true };

if (fs.existsSync(path.join(ROOT, 'bl.config.js'))) {
    blConfig = require(path.join(ROOT, 'bl.config.js'));
    if (blConfig.isUni === undefined) {
        blConfig.isUni = true;
    }
}

module.exports = () => {
    const configs = {
        mode: 'development',
        // mode: 'production',
        entry: entries,
        output: {
            filename: 'static/pages/[name]/render.js',
            path: DIST,
            publicPath: blConfig.publicPath || '//s1.hdslb.com/bfs/static/small-app-web/'
        },
        module: {
            rules: [{
                test: /\.vue$/,
                use: [{
                    loader: 'vue-loader',
                    options: vueLoaderConfig
                },
                {
                    loader: 'uni-vue-loader',
                    options: {
                        platform: 'h5',
                        isUni: blConfig.isUni
                    }
                }
                ]
            },
            {
                test: /\.pug$/,
                oneOf: [
                    // 这条规则应用到 Vue 组件内的 `<template lang="pug">`
                    {
                        resourceQuery: /^\?vue/,
                        use: ['pug-plain-loader']
                    },
                    // 这条规则应用到 JavaScript 内的 pug 导入
                    {
                        use: ['raw-loader', 'pug-plain-loader']
                    }
                ]
            },

            {
                test: /\.json$/,
                use: [{
                    loader: 'uni-json-loader',
                    options: {
                        platform: 'h5'
                    }
                }],
            },
            {
                test: /\.js$/,
                use: [{
                    loader: 'babel-loader'
                },
                {
                    loader: 'uni-js-loader',
                    options: {
                        platform: 'h5'
                    }
                }
                ],
                include: [resolve('src'), resolve('node_modules/webpack-dev-server/client')]
            },
            {
                test: /\.css$/,
                use: ['vue-style-loader', 'css-loader']
            },
            {
                test: /\.less$/,
                use: ['vue-style-loader', 'css-loader', 'less-loader']
            },
            {
                test: /\.styl$/,
                use: ['vue-style-loader', 'css-loader', 'postcss-loader', 'stylus-loader']
            },
            {
                test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'static/img/[name].[hash:7].[ext]'
                }
            },
            {
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                loader: 'url-loader',
                options: {
                    limit: 10000,
                    name: 'static/fonts/[name].[hash:7].[ext]'
                }
            },
            {
                test: /bili-small-app\/runtime\/bl/,
                use: [
                    { loader: 'babel-loader' },
                    {
                        loader: 'string-replace-loader',
                        options: {
                            search: '__BLJS__',
                            replace: 'import bl from \'./bl.web\'',
                            flags: 'g'
                        }
                    }
                ]
            }
            ]
        },
        resolve: {
            alias: {
                '@': ROOT,
                '%': SRC
            }
        },
        plugins: [
            new webpack.DefinePlugin({
                __BLJS__: JSON.stringify('import bl from \'./bl.web\''),
                sapprc: fs.readFileSync(path.join(ROOT, '.sapprc'), 'utf8'),
                'process.env.NODE_ENV': '"production"'
            }),
            new VueLoaderPlugin(),
            new CleanWebpackPlugin(DIST, {
                root: ROOT,
                verbose: false
            }),
            new CopyWebpackPlugin([{
                from: path.join(path.dirname(__dirname), 'dev', 'vue.runtime.js'),
                to: path.join(DIST, 'static', 'vue.runtime.js'),
                ignore: ['.*']
            }]),
            new CopyWebpackPlugin([{
                from: path.join(process.cwd(), 'static'),
                to: path.join(DIST, 'static'),
            }]),
            ...virtualEntries.map(options => new VirtualModulePlugin(options)),
            ...htmlEntries.map(options => new HtmlWebpackPlugin(options)),
            new HtmlWebpackIncludeAssetsPlugin({
                assets: ['static/vue.runtime.js'],
                append: false
            }),
        ]
    };
    if (process.env.BL_NOMIN) {
        configs.optimization = {
            minimize: false
        };
    }
    return configs;
};