const fs = require('fs')
const path = require('path')
const webpack = require('webpack')
const {
  isProd,
  isStaging,
  features
} = require('./feature')

const port = process.env.port || 9527

const copyFiles = [
  { file: 'mediainfo.min.js', from: 'mediainfo.js/dist', to: '.' },
  { file: 'MediaInfoModule.wasm', from: 'mediainfo.js/dist', to: '.' },
  { file: 'spark-md5.min.js', from: 'spark-md5', to: '.' }
]

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

function getCopyFiles () {
  return copyFiles.filter(({ file }) => !fs.existsSync(resolve('public', file))).map(({ file, from, to }) => {
    return { from: resolve('node_modules', from, file), to }
  })
}

module.exports = {
  publicPath: '/',
  outputDir: `dist/${process.env.ENV}`,
  assetsDir: '',
  lintOnSave: isProd,
  productionSourceMap: false,
  devServer: {
    port,
    open: false,
    overlay: {
      warnings: false,
      errors: true
    },
    before: require('./mock/mock-server.js'),
    staticOptions: {
      redirect: true
    }
  },
  configureWebpack: {
    // provide the app's title in webpack's name field, so that
    // it can be accessed in index.html to inject the correct title.
    name: '浪潮屏媒安播云平台',
    resolve: {
      alias: {
        '@': resolve('src')
      }
    },
    performance: {
      maxAssetSize: 5 * 1024 * 1024,
      maxEntrypointSize: 2 * 1024 * 1024
    }
  },
  chainWebpack (config) {
    // it can improve the speed of the first screen, it is recommended to turn on preload
    config.plugin('preload').tap(() => [
      {
        rel: 'preload',
        // to ignore runtime.js
        // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
        include: 'initial'
      }
    ])

    // when there are many pages, it will cause too many meaningless requests
    config.plugins.delete('prefetch')

    config.plugin('feature-flags')
      .use(webpack.DefinePlugin, [features])

    // set svg-sprite-loader
    config.module
      .rule('svg')
      .exclude.add(resolve('src/icons'))
      .end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()

    config.plugin('copy')
      .tap(args => {
        const [patterns, ...oArgs] = args
        return [
          [
            ...patterns,
            ...getCopyFiles()
          ],
          ...oArgs
        ]
      })

    config
      .when(isProd, config => {
        config
          .plugin('ScriptExtHtmlWebpackPlugin')
          .after('html')
          .use('script-ext-html-webpack-plugin', [{
            // `runtime` must same as runtimeChunk name. default is `runtime`
            inline: /runtime\..*\.js$/
          }])
          .end()
        config
          .optimization.splitChunks({
            chunks: 'all',
            cacheGroups: {
              libs: {
                name: 'chunk-libs',
                test: /[\\/]node_modules[\\/]/,
                priority: 10,
                chunks: 'initial' // only package third parties that are initially dependent
              },
              elementUI: {
                name: 'chunk-elementUI', // split elementUI into a single package
                priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
                test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
              },
              commons: {
                name: 'chunk-commons',
                test: resolve('src/components'), // can customize your rules
                minChunks: 3, // minimum common number
                priority: 5,
                reuseExistingChunk: true
              }
            }
          })
          // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
        config
          .optimization.runtimeChunk('single')
          // optimization
        config
          .optimization.minimizer('terser').tap(args => {
            // clear console.x
            args[0].terserOptions.compress.drop_console = !isStaging
            return args
          })
      })
  },
  css: {
    loaderOptions: {
      scss: {
        prependData: `
          @import '~@/scss/helpers/index';
        `
      }
    }
  }
}
