'use strict'
const path = require('path')

// add bash completions to your
//  yargs-powered applications.
module.exports = function completion (yargs, usage, command) {
  const self = {
    completionKey: 'get-yargs-completions'
  }

  const zshShell = (process.env.SHELL && process.env.SHELL.indexOf('zsh') !== -1) ||
    (process.env.ZSH_NAME && process.env.ZSH_NAME.indexOf('zsh') !== -1)
  // get a list of completion commands.
  // 'args' is the array of strings from the line to be completed
  self.getCompletion = function getCompletion (args, done) {
    const completions = []
    const current = args.length ? args[args.length - 1] : ''
    const argv = yargs.parse(args, true)
    const aliases = yargs.parsed.aliases
    const parentCommands = yargs.getContext().commands

    // a custom completion function can be provided
    // to completion().
    if (completionFunction) {
      if (completionFunction.length < 3) {
        const result = completionFunction(current, argv)

        // promise based completion function.
        if (typeof result.then === 'function') {
          return result.then((list) => {
            process.nextTick(() => { done(list) })
          }).catch((err) => {
            process.nextTick(() => { throw err })
          })
        }

        // synchronous completion function.
        return done(result)
      } else {
        // asynchronous completion function
        return completionFunction(current, argv, (completions) => {
          done(completions)
        })
      }
    }

    const handlers = command.getCommandHandlers()
    for (let i = 0, ii = args.length; i < ii; ++i) {
      if (handlers[args[i]] && handlers[args[i]].builder) {
        const builder = handlers[args[i]].builder
        if (typeof builder === 'function') {
          const y = yargs.reset()
          builder(y)
          return y.argv
        }
      }
    }

    if (!current.match(/^-/) && parentCommands[parentCommands.length - 1] !== current) {
      usage.getCommands().forEach((usageCommand) => {
        const commandName = command.parseCommand(usageCommand[0]).cmd
        if (args.indexOf(commandName) === -1) {
          if (!zshShell) {
            completions.push(commandName)
          } else {
            const desc = usageCommand[1] || ''
            completions.push(commandName.replace(/:/g, '\\:') + ':' + desc)
          }
        }
      })
    }

    if (current.match(/^-/) || (current === '' && completions.length === 0)) {
      const descs = usage.getDescriptions()
      Object.keys(yargs.getOptions().key).forEach((key) => {
        // If the key and its aliases aren't in 'args', add the key to 'completions'
        const keyAndAliases = [key].concat(aliases[key] || [])
        const notInArgs = keyAndAliases.every(val => args.indexOf(`--${val}`) === -1)
        if (notInArgs) {
          if (!zshShell) {
            completions.push(`--${key}`)
          } else {
            const desc = descs[key] || ''
            completions.push(`--${key.replace(/:/g, '\\:')}:${desc.replace('__yargsString__:', '')}`)
          }
        }
      })
    }

    done(completions)
  }

  // generate the completion script to add to your .bashrc.
  self.generateCompletionScript = function generateCompletionScript ($0, cmd) {
    const templates = require('./completion-templates')
    let script = zshShell ? templates.completionZshTemplate : templates.completionShTemplate
    const name = path.basename($0)

    // add ./to applications not yet installed as bin.
    if ($0.match(/\.js$/)) $0 = `./${$0}`

    script = script.replace(/{{app_name}}/g, name)
    script = script.replace(/{{completion_command}}/g, cmd)
    return script.replace(/{{app_path}}/g, $0)
  }

  // register a function to perform your own custom
  // completions., this function can be either
  // synchrnous or asynchronous.
  let completionFunction = null
  self.registerFunction = (fn) => {
    completionFunction = fn
  }

  return self
}
