const fs = require('fs')
const path = require('path')
const readPkg = require('read-pkg')
const chalk = require('chalk')
const { warn, error } = require('@vue/cli-shared-utils')
// const { defaults, validate } = require('./options')

module.exports = async function loadUserOptions (context) {
  // controlla.config.js
  let fileConfig, pkgConfig, resolved, resolvedFrom
  const configPath = (
    process.env.CONTROLLA_CLI_SERVICE_CONFIG_PATH ||
    path.resolve(context, 'controlla.config.js')
  )
  if (await fs.existsSync(configPath)) {
    try {
      fileConfig = require(configPath)

      if (typeof fileConfig === 'function') {
        fileConfig = fileConfig()
      }

      if (!fileConfig || typeof fileConfig !== 'object') {
        error(
          `Error loading ${chalk.bold('controlla.config.js')}: should export an object or a function that returns object.`
        )
        fileConfig = null
      }
    } catch (e) {
      error(`Error loading ${chalk.bold('controlla.config.js')}:`)
      throw e
    }
  }

  // package.controlla
  pkgConfig = await resolvePkg(context)
  if (pkgConfig && typeof pkgConfig !== 'object') {
    error(
      `Error loading controlla config in ${chalk.bold(`package.json`)}: ` +
      `the "controlla" field should be an object.`
    )
    pkgConfig = null
  }

  if (fileConfig) {
    if (pkgConfig) {
      warn(
        `"controlla" field in package.json ignored ` +
        `due to presence of ${chalk.bold('controlla.config.js')}.`
      )
      warn(
        `You should migrate it into ${chalk.bold('controlla.config.js')} ` +
        `and remove it from package.json.`
      )
    }
    resolved = fileConfig
  } else {
    if (pkgConfig) {
      resolved = pkgConfig
      resolvedFrom = '"controlla" field in package.json'
    } else {
      resolvedFrom = 'controlla.config.js'
      error(
        `Error loading controlla config in ${chalk.bold(`package.json`)} ` +
        `and error loading ${chalk.bold(resolvedFrom)}`
      )
      return null
    }
  }

  if (typeof resolved.baseUrl !== 'undefined') {
    if (typeof resolved.publicPath !== 'undefined') {
      warn(
        `You have set both "baseUrl" and "publicPath" in ${chalk.bold('controlla.config.js')}, ` +
        `in this case, "baseUrl" will be ignored in favor of "publicPath".`
      )
    } else {
      warn(
        `"baseUrl" option in ${chalk.bold('controlla.config.js')} ` +
        `is deprecated now, please use "publicPath" instead.`
      )
      resolved.publicPath = resolved.baseUrl
    }
  }

  // // validate options
  // validate(resolved, msg => {
  //   error(
  //     `Invalid options in ${chalk.bold(resolvedFrom)}: ${msg}`
  //   )
  // })

  return resolved
}

async function resolvePkg (context) {
  if (await fs.existsSync(path.join(context, 'package.json'))) {
    const pkg = readPkg.sync({ cwd: context })
    return pkg.controlla
  } else {
    return {}
  }
}
