const path = require('path');
// const glob = require('glob');
const webpack = require('webpack');
const fs = require('fs');
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, _src, _config } = require('./getBlConfig');
const ROOT = path.join(process.cwd(), _root);
const SRC = path.join(ROOT, _src);
const DIST = path.join(ROOT, 'dist');
const vueLoaderConfig = require('./vue-loader.conf');
const jsonConditionalCompilation = require('./jsonConditionalCompilation');
const {getLoaderAbsolutePath} = require('./utils');

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

function getIpAddress () {
    var interfaces = require('os').networkInterfaces();
    for (var devName in interfaces) {
        var iface = interfaces[devName];
        for (var i = 0; i < iface.length; i++) {
            var alias = iface[i];
            if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
                return alias.address;
            }
        }
    }
}

// entries

let appConfig = fs.readFileSync(path.join(SRC, 'app.json'), 'utf8');
appConfig = jsonConditionalCompilation({
    content: appConfig,
    platform: 'h5'
});

appConfig = JSON.parse(appConfig);

let entries = {};
appConfig.pages.forEach((conf) => {
    const name = /\/pages\/(.*)/.exec(conf.path)[1];
    entries[name] = `.${_root}${_src}${conf.path}/index.js`; // ./src...
});

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

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


let firstPage = appConfig.pages[0].path;
const firstPageArr = firstPage.split('/');
firstPage = firstPageArr[firstPageArr.length - 1];

let blConfig = { dev: {}, isUni: true };

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

// 解析用户的npm执行命令
const command = process.env.npm_config_argv ? JSON.parse(process.env.npm_config_argv): {};
// 请求配置的信息传入
const temp = {
    // 默认接口指定请求环境
    env: 'production'
};
// 自定义命令解析，知否制定运行环境dev变量
if (command.original && command.original[2]) {
    temp.env = /-(.+)$/.exec(command.original[2])[1];
}

const configs = {
    mode: 'development',
    // mode: 'production',
    devtool: '#cheap-module-eval-source-map',
    entry: entries,
    output: {
        filename: 'static/pages/[name]/render.js',
        path: DIST,
        publicPath: '/'
    },
    module: {
        rules: [{
            test: /\.vue$/,
            use: [{
                loader: 'vue-loader',
                options: vueLoaderConfig
            },
            {
                loader: path.resolve(__dirname, './loaders/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: /\.ts$/,
            use: [{
                loader: 'babel-loader'
            },
            {
                loader: 'uni-js-loader',
                options: {
                    platform: 'h5'
                }
            }, {
                loader: 'ts-loader',
                options: {
                    transpileOnly: true,
                    appendTsSuffixTo: [
                        '\\.vue$'
                    ]
                }
            }]
        },
        {
            test: /\.css$/,
            use: ['vue-style-loader', getLoaderAbsolutePath('css-loader'), 'postcss-loader']
        },
        {
            test: /\.less$/,
            use: ['vue-style-loader', getLoaderAbsolutePath('css-loader'), 'postcss-loader', 'less-loader']
        },
        {
            test: /\.styl$/,
            use: ['vue-style-loader', getLoaderAbsolutePath('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
        },
        extensions: ['.js', '.ts', '.tsx', '.vue', '.less', '.css', '.styl']
    },
    plugins: [
        new webpack.DefinePlugin({
            __BLJS__: JSON.stringify('import bl from \'./bl.web\''),
            sapprc: fs.readFileSync(path.join(ROOT, _config, '.sapprc'), 'utf8'),
            'process.env.NODE_ENV': '"development"',
            'process.env.request': JSON.stringify(temp)
        }),
        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: ['.*']
        }]),
        ...virtualEntries.map(options => new VirtualModulePlugin(options)),
        ...htmlEntries.map(options => new HtmlWebpackPlugin(options)),
        new HtmlWebpackIncludeAssetsPlugin({
            assets: ['static/vue.runtime.js'],
            append: false
        })
    ],
    externals: {
        vue: 'Vue'
    },
    devServer: {
        host: blConfig.dev && blConfig.dev.host || getIpAddress(),
        port: blConfig.dev && blConfig.dev.port || 8080,
        contentBase: path.join(ROOT),
        open: true,
        openPage: `${firstPage}.html`,
        proxy: {
            '/api/miniapp': {
                target: 'http://miniapp.bilibili.com',
                secure: false,
                changeOrigin: true
            },
            '/api/applet': {
                target: 'http://miniapp.bilibili.com',
                secure: false,
                changeOrigin: true
            },
            '/api': {
                target: 'https://mall.bilibili.com/mall-c',
                secure: false,
                changeOrigin: true
            },
            '/miniapp-b/miniapp': {
                target: 'http://miniapp.bilibili.com',
                secure: false,
                changeOrigin: true
            },
            '/ticket': {
                target: 'http://show.bilibili.com/api',
                secure: false,
                changeOrigin: true
            },
            '/cart/na': {
                target: 'https://mall.bilibili.com/mall-c',
                secure: false,
                changeOrigin: true
            }
        }
    }
};
if (process.env.BL_NOMIN) {
    configs.optimization = {
        minimize: false
    };
}
module.exports = configs;
