const path = require('path')
const fs = require('fs')
const compressing = require('compressing')
const axios = require('axios')
const child_process = require('child_process')
const packageJson = require('../package.json')
function parseTime(time, format = 'yyyy-MM-dd hh:mm:ss') {
  const date = time instanceof Date ? time : new Date(time)

  const o = {
    'M+': date.getMonth() + 1, // 月份
    'd+': date.getDate(), // 日
    'h+': date.getHours(), // 小时
    'm+': date.getMinutes(), // 分
    's+': date.getSeconds(), // 秒
    'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
    'S': date.getMilliseconds() // 毫秒
  }
  if (/(y+)/.test(format)) {
    format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  }
  for (const k in o) {
    if (new RegExp('(' + k + ')').test(format)) {
      format = format.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
    }
  }
  return format
}

/**
 * 打包插件 v2.0
 * youfool
 */
class IncrePack {
  apply(compiler) {
    if (process.env.VUE_APP_WEBPACK_CMD !== 'build') {
      return
    }
    const date = new Date()
    const projectPath = path.join(__dirname, '../')
    const distPath = projectPath + 'dist'
    const versionPath = `${projectPath}src/version.js`
    let hash = '000000'
    try {
      hash = child_process.execSync('git rev-parse HEAD').slice(0, 6)
    } catch (e) {
      console.log('------------------读取版本Hash失败---------------')
      console.warn(e)
    }
    const codeVersion = `${parseTime(date, 'yyyy-MM-dd hh:mm:ss')} ${hash} ${process.env.VUE_APP_ENVIRONMENT}`
    compiler.hooks.beforeRun.tapAsync('SetVersion', async(compilation, callback) => {
      const data = `/** 本文件由打包插件自动生成和修改 */\nexport default '${codeVersion}'\n`
      fs.writeFileSync(versionPath, data)
      callback()
    })
    compiler.hooks.done.tap('SetVersion', async(compilation) => {
      const data = `/** 本文件由打包插件自动生成和修改 */\nexport default ''\n`
      fs.writeFileSync(versionPath, data)
    })
    compiler.hooks.done.tap('IncrePack', async(compilation) => {
      let versionJson = {
        artifactId: packageJson.name,
        version: packageJson.version,
        appId: packageJson.appId,
        codeId: packageJson.codeId,
        codeVersion
      }
      if (packageJson.increApi) {
        // 获取版本信息
        try {
          console.log('------------------正在写入升级记录---------------')
          const res = await axios.default({
            url: packageJson.increApi + '?appId=' + packageJson.appId + '&codeId=' + packageJson.codeId,
            method: 'get',
            timeout: 5000
          })
          const { code, data } = res.data
          if (code === 0 && data) {
            versionJson = {
              ...versionJson,
              artifactId: packageJson.name,
              upgradeId: data.upgradeId,
              version: data.version,
              releaseTime: data.releaseTime,
              fromCommit: data.fromCommit,
              untilCommit: data.untilCommit,
              newFeatures: data.newFeatures,
              repair: data.repair,
              other: data.other
            }
            console.log('------------------写入升级记录成功---------------')
          }
        } catch (e) {
          console.log(e.message)
          console.log('------------------提交升级记录到远端失败---------------')
        }
      }
      fs.mkdirSync(distPath + '/increpack-config')
      fs.writeFileSync(distPath + '/increpack-config/version.json', JSON.stringify(versionJson), 'utf8')
      const increName = `${packageJson.name}-${process.env.VUE_APP_ENVIRONMENT}-${parseTime(date, 'yyyy-MM-dd')}-${hash}.zip`
      // 打包压缩
      const tempFile = projectPath + '/' + increName
      compressing.zip.compressDir(distPath, tempFile, { ignoreBase: true })
        .then(() => {
          // 剪切回dist目录下
          fs.renameSync(tempFile, distPath + '/' + increName)
          console.log('------------------打包成功------------------')
        })
        .catch(err => {
          console.error(err)
        })
    })
  }
}
module.exports = IncrePack
