/* eslint-disable filenames/match-regex */
const path = require('path')
const webpack = require('webpack')
const AliasPlugin = require('enhanced-resolve/lib/AliasPlugin')
const CircularDependencyPlugin = require('circular-dependency-plugin')
const { argv } = require('yargs')
const openInEditor = require('launch-editor-middleware')
const designVariables = require('./src/common/design/variables.js')

function isInSrc(context) {
  // 判断当前上下文是否属于src目录
  const srcPath = path.resolve(__dirname, 'src')
  return context === srcPath || context.startsWith(srcPath + path.sep)
}

const replaceRelative = new webpack.NormalModuleReplacementPlugin(/^\..*/, function(resource) {
  // 将相对路径改写为完整路径，便于在custom和src目录搜索
  const requstFullPath = path.resolve(resource.context, resource.request)
  // 不是src目录发起的 或 不是引用src目录的文件，退出
  // 比如请求node_module下的文件时，不处理
  if (!isInSrc(resource.context) || !isInSrc(requstFullPath)) return

  let p = path.resolve(resource.context, resource.request).replace(__dirname, '')
  p = p.replace(/\\/g, '/').replace('/src/', '')
  // console.warn('\nReplace path:', resource.request, p)
  resource.request = p
})
const replaceAtSign = new webpack.NormalModuleReplacementPlugin(/^@.*/, function(resource) {
  // 将@开始的路径改写为完整路径，便于在custom和src目录搜索
  if (!isInSrc(resource.context)) return

  const p = resource.request.replace('@/', '')
  // console.warn('\n@Replace path:', resource.request, p)
  resource.request = p
})
let appConfigCustom
try {
  appConfigCustom = require('./src_custom/app-config.js')
} catch (e) {
  appConfigCustom = {}
}

const appConfig = appConfigCustom

// 各种API地址，转发到后台服务器
const proxy = {}
const proxySetting = {
  target: appConfig.apiEndpoint || 'https://192.168.2.177:8898/xcoa',
  secure: false,
  changeOrigin: true,
  // 转发时去掉虚拟的路径
  pathRewrite: { '^/-app-': '' },
  logLevel: 'debug',
}
const paths = ['api', 'docviewer-webapp', ...(appConfig.apiPaths || [])]
paths.forEach((path) => {
  proxy['/-app-/' + path] = proxySetting
})

process.env.VUE_APP_TITLE = appConfig.appTitle || 'GRC.Platform'

module.exports = {
  publicPath: '',
  transpileDependencies: [
    'ant-design-vue',
    'vue-echarts',
    'resize-detector',
    'signature_pad',
    'sm-crypto',
  ],
  devServer: {
    // 本地的开发服务器也加一个app路径，模拟真实环境
    // 注意访问的时候要加上这个虚拟路径，如：http://localhost:8080/-app-/
    publicPath: '/-app-/',
    port: appConfig.devServerPort || 8080,
    proxy,
    // 处理mock数据
    before(app) {
      app.use('/__open-in-editor', openInEditor('code'))
      require('./src/_mock').getBeforeHook(app)
    },
    // 允许通过域名访问
    disableHostCheck: true,
    // 静态资源存放的目录，如indidoc安装文件
    contentBase: [path.join(__dirname, 'src_custom', 'www')],
    contentBasePublicPath: '/-app-',
  },
  configureWebpack: (config) => {
    // sass处理器会把\xxxx转义的字符，转义回中文。用css-unicode-loader再次转成\xxxx
    const sassLoader = require.resolve('sass-loader')
    config.module.rules
      .filter((rule) => {
        if (!rule.test) return false
        return rule.test.toString().indexOf('scss') !== -1
      })
      .forEach((rule) => {
        rule.oneOf.forEach((oneOfRule) => {
          const sassLoaderIndex = oneOfRule.use.findIndex((item) => item.loader === sassLoader)
          oneOfRule.use.splice(sassLoaderIndex, 0, {
            loader: require.resolve('css-unicode-loader'),
          })
        })
      })

    const plugins = [
      replaceRelative,
      replaceAtSign,
      new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /zh-cn/),
    ]
    if (argv.analyseCircularDependency) {
      plugins.push(
        new CircularDependencyPlugin({
          exclude: /node_modules/,
          include: /src/,
          failOnError: true,
          allowAsyncCycles: false,
          cwd: process.cwd(),
        })
      )
    }
    return {
      plugins,
      resolve: {
        plugins: [
          new AliasPlugin(
            'described-resolve',
            [
              {
                name: '@extension-points',
                alias: [
                  path.resolve('src_custom', '_extension-points'),
                  path.resolve('src', '_extension-points'),
                ],
              },
            ],
            'resolve'
          ),
        ],
      },
    }
  },
  /**
   * @param {import('webpack-chain')} config
   */
  chainWebpack: (config) => {
    config.resolve.alias
      .set('@custom', path.resolve('src_custom'))
      .set('@product', path.resolve('src_product'))
      .set('@external', path.resolve('lib-external'))
    // 把项目定制目录放在平台目录前面，可以覆盖
    config.resolve.modules.add(path.resolve(__dirname, 'src_custom/_override'))
    config.resolve.modules.add(path.resolve(__dirname, 'src'))
    config.plugin('html').tap((args) => {
      args[0].title = process.env.VUE_APP_TITLE
      args[0].primaryColor = designVariables['primary-color']
      return args
    })
    // 避免moment被打包多次的问题
    config.resolve.alias.set('moment$', path.resolve(__dirname, 'node_modules/moment/moment.js'))
    if ((process.env.NODE_ENV === 'production' && !argv.enableSourceMap) || argv.disableSourceMap) {
      config.devtool('(none)')
    }
    config.plugins.delete('prefetch')
    config.plugins.delete('preload')
  },
  css: {
    requireModuleExtension: true,
    loaderOptions: {
      css: {
        // js中可以使用camelCase获取classname
        localsConvention: 'camelCase',
        modules: {
          // css moudule 生成的class规则：原class+组件名+模块名
          localIdentName: '[local]_[name]_[1]',
          localIdentRegExp: /src.([a-z-]*)/i,
        },
      },
      less: {
        modifyVars: designVariables,
        javascriptEnabled: true,
      },
    },
  },
}
