const fs = require('fs')
const path = require('path')

const apis = require('../lib/apis')

const AUTO_LOADS = [
  'upx2px',
  'canIUse',

  'getSystemInfo',
  'getSystemInfoSync',

  'navigateTo',
  'redirectTo',
  'switchTab',
  'reLaunch',
  'navigateBack'
]

const TOAST_DEPS = [
  ['/platforms/h5/components/app/popup/toast.vue', 'Toast'],
  ['/platforms/h5/components/app/popup/mixins/toast.js', 'ToastMixin']
]

// TODO 暂不考虑 head,tabBar 的动态拆分
const DEPS = {
  chooseLocation: [
    ['/platforms/h5/view/components/map/index.vue', 'Map'],
    ['/core/view/components/input/index.vue', 'Input'],
    ['/core/view/components/scroll-view/index.vue', 'ScrollView'],
    ['/platforms/h5/service/api/network/request.js', 'request'],
    ['/platforms/h5/service/api/location/get-location.js', 'getLocation'],
    ['/platforms/h5/components/system-routes/choose-location/index.vue', 'ChooseLocation']
  ],
  openLocation: [
    ['/platforms/h5/view/components/map/index.vue', 'Map'],
    ['/platforms/h5/service/api/network/request.js', 'request'],
    ['/platforms/h5/service/api/location/get-location.js', 'getLocation'],
    ['/platforms/h5/components/system-routes/open-location/index.vue', 'OpenLocation']
  ],
  getLocation: [
    ['/platforms/h5/service/api/network/request.js', 'request']
  ],
  previewImage: [
    ['/core/view/components/swiper/index.vue', 'Swiper'],
    ['/core/view/components/swiper-item/index.vue', 'SwiperItem'],
    ['/core/view/components/movable-area/index.vue', 'MovableArea'],
    ['/core/view/components/movable-view/index.vue', 'MovableView'],
    [
      '/platforms/h5/components/app/popup/preview-image/index.vue',
      'PreviewImage'
    ],
    [
      '/platforms/h5/components/app/popup/mixins/preview-image.js',
      'PreviewImageMixin'
    ]
  ],
  showToast: TOAST_DEPS,
  hideToast: TOAST_DEPS,
  showLoading: TOAST_DEPS,
  hideLoading: TOAST_DEPS,
  showModal: [
    ['/platforms/h5/components/app/popup/modal.vue', 'Modal'],
    ['/platforms/h5/components/app/popup/mixins/modal.js', 'ModalMixin']
  ],
  showActionSheet: [
    ['/platforms/h5/components/app/popup/actionSheet.vue', 'ActionSheet'],
    ['/platforms/h5/components/app/popup/mixins/action-sheet.js', 'ActionSheetMixin']
  ],
  createSelectorQuery: [
    ['/core/view/bridge/subscribe/api/request-component-info.js', 'requestComponentInfo']
  ],
  createIntersectionObserver: [
    ['/core/view/bridge/subscribe/api/request-component-observer.js', 'requestComponentObserver'],
    ['/core/view/bridge/subscribe/api/request-component-observer.js', 'destroyComponentObserver']
  ],
  createMediaQueryObserver: [
    ['/core/view/bridge/subscribe/api/request-media-query-observer.js', 'requestMediaQueryObserver'],
    ['/core/view/bridge/subscribe/api/request-media-query-observer.js', 'destroyMediaQueryObserver']
  ]
}

// 检查依赖文件是否存在
Object.keys(DEPS).reduce(function (depFiles, name) {
  DEPS[name].forEach(function (dep) {
    depFiles.add(dep[0])
  })
  return depFiles
}, new Set()).forEach(file => {
  if (!fs.existsSync(path.join(__dirname, '../src', file))) {
    console.error(file + ' 不存在')
    process.exit(0)
  }
})

function parseApiManifestDeps (manifest, protocol) {
  // 解析 platform 依赖
  Object.keys(manifest).forEach(name => {
    const deps = manifest[name][1]
    if (deps.length) {
      deps.forEach(dep => {
        if (manifest[dep[1]]) {
          dep[0] = manifest[dep[1]][0]
        } else {
          console.error(`依赖模块[${dep[1]}]不存在,删除 ${name} 接口\n`)
          delete manifest[name]
        }
      })
    }
  })
  // 解析 protocol 依赖
  Object.keys(manifest).forEach(name => {
    const deps = manifest[name][1]
    if (protocol[name]) {
      deps.push([protocol[name], name])
    } else {
      console.warn(`${name} 缺少 protocol`)
    }
  })
  // 追加默认依赖
  Object.keys(DEPS).forEach(name => {
    if (manifest[name]) {
      manifest[name][1].push(...DEPS[name])
    } else {
      console.error(`缺少 ${name}`)
    }
  })
  // 设置自动加载标记
  AUTO_LOADS.forEach(name => {
    if (manifest[name]) {
      manifest[name][2] = true
    } else {
      console.error(`缺少 ${name}`)
    }
  })
}

module.exports = {
  generateApiManifest (manifest, protocol) {
    if (!Object.keys(manifest).length) {
      throw new Error('api manifest.json 生成失败')
    }
    parseApiManifestDeps(manifest, protocol)

    const manifestJson = Object.create(null)
    const todoApis = []
    apis.forEach(name => {
      if (manifest[name]) {
        manifestJson[name] = manifest[name]
      } else {
        todoApis.push(name)
      }
    })

    if (todoApis.length) {
      console.log('\n')
      console.warn(`${process.env.UNI_PLATFORM} 平台缺少以下 API  实现(共 ${todoApis.length} 个)`)
      todoApis.forEach(name => {
        console.warn(name)
      })
    }

    fs.writeFileSync(path.resolve(__dirname, '../packages/uni-' + process.env.UNI_PLATFORM + '/manifest.json'),
      JSON.stringify(manifestJson, null, 4)
    )
  }
}
