'use strict'

const path = require('path')
const yargs = require('yargs')
const fs = require('graceful-fs')

const Server = require('./server')
const helper = require('./helper')
const constant = require('./constants')
const cfg = require('./config')

function processArgs (argv, options, fs, path) {
  Object.getOwnPropertyNames(argv).forEach(function (name) {
    let argumentValue = argv[name]
    if (name !== '_' && name !== '$0') {
      if (Array.isArray(argumentValue)) {
        argumentValue = argumentValue.pop() // If the same argument is defined multiple times, override.
      }
      options[helper.dashToCamel(name)] = argumentValue
    }
  })

  if (helper.isString(options.autoWatch)) {
    options.autoWatch = options.autoWatch === 'true'
  }

  if (helper.isString(options.colors)) {
    options.colors = options.colors === 'true'
  }

  if (helper.isString(options.failOnEmptyTestSuite)) {
    options.failOnEmptyTestSuite = options.failOnEmptyTestSuite === 'true'
  }

  if (helper.isString(options.failOnFailingTestSuite)) {
    options.failOnFailingTestSuite = options.failOnFailingTestSuite === 'true'
  }

  if (helper.isString(options.formatError)) {
    let required
    try {
      required = require(options.formatError)
    } catch (err) {
      console.error('Could not require formatError: ' + options.formatError, err)
    }
    // support exports.formatError and module.exports = function
    options.formatError = required.formatError || required
    if (!helper.isFunction(options.formatError)) {
      console.error(`Format error must be a function, got: ${typeof options.formatError}`)
      process.exit(1)
    }
  }

  if (helper.isString(options.logLevel)) {
    const logConstant = constant['LOG_' + options.logLevel.toUpperCase()]
    if (helper.isDefined(logConstant)) {
      options.logLevel = logConstant
    } else {
      console.error('Log level must be one of disable, error, warn, info, or debug.')
      process.exit(1)
    }
  } else if (helper.isDefined(options.logLevel)) {
    console.error('Log level must be one of disable, error, warn, info, or debug.')
    process.exit(1)
  }

  if (helper.isString(options.singleRun)) {
    options.singleRun = options.singleRun === 'true'
  }

  if (helper.isString(options.browsers)) {
    options.browsers = options.browsers.split(',')
  }

  if (options.reportSlowerThan === false) {
    options.reportSlowerThan = 0
  }

  if (helper.isString(options.reporters)) {
    options.reporters = options.reporters.split(',')
  }

  if (helper.isString(options.removedFiles)) {
    options.removedFiles = options.removedFiles.split(',')
  }

  if (helper.isString(options.addedFiles)) {
    options.addedFiles = options.addedFiles.split(',')
  }

  if (helper.isString(options.changedFiles)) {
    options.changedFiles = options.changedFiles.split(',')
  }

  if (helper.isString(options.refresh)) {
    options.refresh = options.refresh === 'true'
  }

  let configFile = argv.configFile

  if (!configFile) {
    // default config file (if exists)
    if (fs.existsSync('./karma.conf.js')) {
      configFile = './karma.conf.js'
    } else if (fs.existsSync('./karma.conf.coffee')) {
      configFile = './karma.conf.coffee'
    } else if (fs.existsSync('./karma.conf.ts')) {
      configFile = './karma.conf.ts'
    } else if (fs.existsSync('./.config/karma.conf.js')) {
      configFile = './.config/karma.conf.js'
    } else if (fs.existsSync('./.config/karma.conf.coffee')) {
      configFile = './.config/karma.conf.coffee'
    } else if (fs.existsSync('./.config/karma.conf.ts')) {
      configFile = './.config/karma.conf.ts'
    }
  }

  options.configFile = configFile ? path.resolve(configFile) : null

  if (options.cmd === 'run') {
    options.clientArgs = parseClientArgs(process.argv)
  }

  return options
}

function parseClientArgs (argv) {
  // extract any args after '--' as clientArgs
  let clientArgs = []
  argv = argv.slice(2)
  const idx = argv.indexOf('--')
  if (idx !== -1) {
    clientArgs = argv.slice(idx + 1)
  }
  return clientArgs
}

// return only args that occur before `--`
function argsBeforeDoubleDash (argv) {
  const idx = argv.indexOf('--')

  return idx === -1 ? argv : argv.slice(0, idx)
}

function describeRoot () {
  return yargs
    .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
      'Run --help with particular command to see its description and available options.\n\n' +
      'Usage:\n' +
      '  $0 <command>')
    .command('init [configFile]', 'Initialize a config file.', describeInit)
    .command('start [configFile]', 'Start the server / do a single run.', describeStart)
    .command('run [configFile]', 'Trigger a test run.', describeRun)
    .command('stop [configFile]', 'Stop the server.', describeStop)
    .command('completion', 'Shell completion for karma.', describeCompletion)
    .demandCommand(1, 'Command not specified.')
    .strictCommands()
    .describe('help', 'Print usage and options.')
    .describe('version', 'Print current version.')
}

function describeInit (yargs) {
  yargs
    .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
      'INIT - Initialize a config file.\n\n' +
      'Usage:\n' +
      '  $0 init [configFile]')
    .strictCommands(false)
    .version(false)
    .positional('configFile', {
      describe: 'Name of the generated Karma configuration file',
      type: 'string'
    })
    .describe('log-level', '<disable | error | warn | info | debug> Level of logging.')
    .describe('colors', 'Use colors when reporting and printing logs.')
    .describe('no-colors', 'Do not use colors when reporting or printing logs.')
}

function describeStart (yargs) {
  yargs
    .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
      'START - Start the server / do a single run.\n\n' +
      'Usage:\n' +
      '  $0 start [configFile]')
    .strictCommands(false)
    .version(false)
    .positional('configFile', {
      describe: 'Path to the Karma configuration file',
      type: 'string'
    })
    .describe('port', '<integer> Port where the server is running.')
    .describe('auto-watch', 'Auto watch source files and run on change.')
    .describe('detached', 'Detach the server.')
    .describe('no-auto-watch', 'Do not watch source files.')
    .describe('log-level', '<disable | error | warn | info | debug> Level of logging.')
    .describe('colors', 'Use colors when reporting and printing logs.')
    .describe('no-colors', 'Do not use colors when reporting or printing logs.')
    .describe('reporters', 'List of reporters (available: dots, progress, junit, growl, coverage).')
    .describe('browsers', 'List of browsers to start (eg. --browsers Chrome,ChromeCanary,Firefox).')
    .describe('capture-timeout', '<integer> Kill browser if does not capture in given time [ms].')
    .describe('single-run', 'Run the test when browsers captured and exit.')
    .describe('no-single-run', 'Disable single-run.')
    .describe('report-slower-than', '<integer> Report tests that are slower than given time [ms].')
    .describe('fail-on-empty-test-suite', 'Fail on empty test suite.')
    .describe('no-fail-on-empty-test-suite', 'Do not fail on empty test suite.')
    .describe('fail-on-failing-test-suite', 'Fail on failing test suite.')
    .describe('no-fail-on-failing-test-suite', 'Do not fail on failing test suite.')
    .option('format-error', {
      describe: 'A path to a file that exports the format function.',
      type: 'string'
    })
}

function describeRun (yargs) {
  yargs
    .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
      'RUN - Run the tests (requires running server).\n\n' +
      'Usage:\n' +
      '  $0 run [configFile] [-- <clientArgs>]')
    .strictCommands(false)
    .version(false)
    .positional('configFile', {
      describe: 'Path to the Karma configuration file',
      type: 'string'
    })
    .describe('port', '<integer> Port where the server is listening.')
    .describe('no-refresh', 'Do not re-glob all the patterns.')
    .describe('fail-on-empty-test-suite', 'Fail on empty test suite.')
    .describe('no-fail-on-empty-test-suite', 'Do not fail on empty test suite.')
    .describe('log-level', '<disable | error | warn | info | debug> Level of logging.')
    .describe('colors', 'Use colors when reporting and printing logs.')
    .describe('no-colors', 'Do not use colors when reporting or printing logs.')
    .option('removed-files', {
      describe: 'Comma-separated paths to removed files. Useful when automatic file watching is disabled.',
      type: 'string'
    })
    .option('changed-files', {
      describe: 'Comma-separated paths to changed files. Useful when automatic file watching is disabled.',
      type: 'string'
    })
    .option('added-files', {
      describe: 'Comma-separated paths to added files. Useful when automatic file watching is disabled.',
      type: 'string'
    })
}

function describeStop (yargs) {
  yargs
    .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
      'STOP - Stop the server (requires running server).\n\n' +
      'Usage:\n' +
      '  $0 stop [configFile]')
    .strictCommands(false)
    .version(false)
    .positional('configFile', {
      describe: 'Path to the Karma configuration file',
      type: 'string'
    })
    .describe('port', '<integer> Port where the server is listening.')
    .describe('log-level', '<disable | error | warn | info | debug> Level of logging.')
}

function describeCompletion (yargs) {
  yargs
    .usage('Karma - Spectacular Test Runner for JavaScript.\n\n' +
      'COMPLETION - Bash/ZSH completion for karma.\n\n' +
      'Installation:\n' +
      '  $0 completion >> ~/.bashrc')
    .version(false)
}

function printRunnerProgress (data) {
  process.stdout.write(data)
}

exports.process = () => {
  const argv = describeRoot().parse(argsBeforeDoubleDash(process.argv.slice(2)))
  return processArgs(argv, { cmd: argv._.shift() }, fs, path)
}

exports.run = async () => {
  const cliOptions = exports.process()
  const cmd = cliOptions.cmd // prevent config from changing the command
  const cmdNeedsConfig = cmd === 'start' || cmd === 'run' || cmd === 'stop'
  if (cmdNeedsConfig) {
    let config
    try {
      config = await cfg.parseConfig(
        cliOptions.configFile,
        cliOptions,
        {
          promiseConfig: true,
          throwErrors: true
        }
      )
    } catch (karmaConfigException) {
      // The reject reason/exception isn't used to log a message since
      // parseConfig already calls a configured logger method with an almost
      // identical message.

      // The `run` function is a private application, not a public API. We don't
      // need to worry about process.exit vs throw vs promise rejection here.
      process.exit(1)
    }
    switch (cmd) {
      case 'start': {
        const server = new Server(config)
        await server.start()
        return server
      }
      case 'run':
        return require('./runner')
          .run(config)
          .on('progress', printRunnerProgress)
      case 'stop':
        return require('./stopper').stop(config)
    }
  } else {
    switch (cmd) {
      case 'init':
        return require('./init').init(cliOptions)
      case 'completion':
        return require('./completion').completion(cliOptions)
    }
  }
}

// just for testing
exports.processArgs = processArgs
exports.parseClientArgs = parseClientArgs
exports.argsBeforeDoubleDash = argsBeforeDoubleDash
