'use strict'
// this file handles outputting usage instructions,
// failures, etc. keeps logging in one place.
const decamelize = require('decamelize')
const stringWidth = require('string-width')
const objFilter = require('./obj-filter')
const path = require('path')
const setBlocking = require('set-blocking')
const YError = require('./yerror')

module.exports = function usage (yargs, y18n) {
  const __ = y18n.__
  const self = {}

  // methods for ouputting/building failure message.
  const fails = []
  self.failFn = function failFn (f) {
    fails.push(f)
  }

  let failMessage = null
  let showHelpOnFail = true
  self.showHelpOnFail = function showHelpOnFailFn (enabled, message) {
    if (typeof enabled === 'string') {
      message = enabled
      enabled = true
    } else if (typeof enabled === 'undefined') {
      enabled = true
    }
    failMessage = message
    showHelpOnFail = enabled
    return self
  }

  let failureOutput = false
  self.fail = function fail (msg, err) {
    const logger = yargs._getLoggerInstance()

    if (fails.length) {
      for (let i = fails.length - 1; i >= 0; --i) {
        fails[i](msg, err, self)
      }
    } else {
      if (yargs.getExitProcess()) setBlocking(true)

      // don't output failure message more than once
      if (!failureOutput) {
        failureOutput = true
        if (showHelpOnFail) {
          yargs.showHelp('error')
          logger.error()
        }
        if (msg || err) logger.error(msg || err)
        if (failMessage) {
          if (msg || err) logger.error('')
          logger.error(failMessage)
        }
      }

      err = err || new YError(msg)
      if (yargs.getExitProcess()) {
        return yargs.exit(1)
      } else if (yargs._hasParseCallback()) {
        return yargs.exit(1, err)
      } else {
        throw err
      }
    }
  }

  // methods for ouputting/building help (usage) message.
  let usages = []
  let usageDisabled = false
  self.usage = (msg, description) => {
    if (msg === null) {
      usageDisabled = true
      usages = []
      return
    }
    usageDisabled = false
    usages.push([msg, description || ''])
    return self
  }
  self.getUsage = () => {
    return usages
  }
  self.getUsageDisabled = () => {
    return usageDisabled
  }

  self.getPositionalGroupName = () => {
    return __('Positionals:')
  }

  let examples = []
  self.example = (cmd, description) => {
    examples.push([cmd, description || ''])
  }

  let commands = []
  self.command = function command (cmd, description, isDefault, aliases) {
    // the last default wins, so cancel out any previously set default
    if (isDefault) {
      commands = commands.map((cmdArray) => {
        cmdArray[2] = false
        return cmdArray
      })
    }
    commands.push([cmd, description || '', isDefault, aliases])
  }
  self.getCommands = () => commands

  let descriptions = {}
  self.describe = function describe (key, desc) {
    if (typeof key === 'object') {
      Object.keys(key).forEach((k) => {
        self.describe(k, key[k])
      })
    } else {
      descriptions[key] = desc
    }
  }
  self.getDescriptions = () => descriptions

  let epilogs = []
  self.epilog = (msg) => {
    epilogs.push(msg)
  }

  let wrapSet = false
  let wrap
  self.wrap = (cols) => {
    wrapSet = true
    wrap = cols
  }

  function getWrap () {
    if (!wrapSet) {
      wrap = windowWidth()
      wrapSet = true
    }

    return wrap
  }

  const deferY18nLookupPrefix = '__yargsString__:'
  self.deferY18nLookup = str => deferY18nLookupPrefix + str

  const defaultGroup = 'Options:'
  self.help = function help () {
    if (cachedHelpMessage) return cachedHelpMessage
    normalizeAliases()

    // handle old demanded API
    const base$0 = yargs.customScriptName ? yargs.$0 : path.basename(yargs.$0)
    const demandedOptions = yargs.getDemandedOptions()
    const demandedCommands = yargs.getDemandedCommands()
    const groups = yargs.getGroups()
    const options = yargs.getOptions()

    let keys = []
    keys = keys.concat(Object.keys(descriptions))
    keys = keys.concat(Object.keys(demandedOptions))
    keys = keys.concat(Object.keys(demandedCommands))
    keys = keys.concat(Object.keys(options.default))
    keys = keys.filter(filterHiddenOptions)
    keys = Object.keys(keys.reduce((acc, key) => {
      if (key !== '_') acc[key] = true
      return acc
    }, {}))

    const theWrap = getWrap()
    const ui = require('cliui')({
      width: theWrap,
      wrap: !!theWrap
    })

    // the usage string.
    if (!usageDisabled) {
      if (usages.length) {
        // user-defined usage.
        usages.forEach((usage) => {
          ui.div(`${usage[0].replace(/\$0/g, base$0)}`)
          if (usage[1]) {
            ui.div({ text: `${usage[1]}`, padding: [1, 0, 0, 0] })
          }
        })
        ui.div()
      } else if (commands.length) {
        let u = null
        // demonstrate how commands are used.
        if (demandedCommands._) {
          u = `${base$0} <${__('command')}>\n`
        } else {
          u = `${base$0} [${__('command')}]\n`
        }
        ui.div(`${u}`)
      }
    }

    // your application's commands, i.e., non-option
    // arguments populated in '_'.
    if (commands.length) {
      ui.div(__('Commands:'))

      const context = yargs.getContext()
      const parentCommands = context.commands.length ? `${context.commands.join(' ')} ` : ''

      if (yargs.getParserConfiguration()['sort-commands'] === true) {
        commands = commands.sort((a, b) => a[0].localeCompare(b[0]))
      }

      commands.forEach((command) => {
        const commandString = `${base$0} ${parentCommands}${command[0].replace(/^\$0 ?/, '')}` // drop $0 from default commands.
        ui.span(
          {
            text: commandString,
            padding: [0, 2, 0, 2],
            width: maxWidth(commands, theWrap, `${base$0}${parentCommands}`) + 4
          },
          { text: command[1] }
        )
        const hints = []
        if (command[2]) hints.push(`[${__('default:').slice(0, -1)}]`) // TODO hacking around i18n here
        if (command[3] && command[3].length) {
          hints.push(`[${__('aliases:')} ${command[3].join(', ')}]`)
        }
        if (hints.length) {
          ui.div({ text: hints.join(' '), padding: [0, 0, 0, 2], align: 'right' })
        } else {
          ui.div()
        }
      })

      ui.div()
    }

    // perform some cleanup on the keys array, making it
    // only include top-level keys not their aliases.
    const aliasKeys = (Object.keys(options.alias) || [])
      .concat(Object.keys(yargs.parsed.newAliases) || [])

    keys = keys.filter(key => !yargs.parsed.newAliases[key] && aliasKeys.every(alias => (options.alias[alias] || []).indexOf(key) === -1))

    // populate 'Options:' group with any keys that have not
    // explicitly had a group set.
    if (!groups[defaultGroup]) groups[defaultGroup] = []
    addUngroupedKeys(keys, options.alias, groups)

    // display 'Options:' table along with any custom tables:
    Object.keys(groups).forEach((groupName) => {
      if (!groups[groupName].length) return

      // if we've grouped the key 'f', but 'f' aliases 'foobar',
      // normalizedKeys should contain only 'foobar'.
      const normalizedKeys = groups[groupName].filter(filterHiddenOptions).map((key) => {
        if (~aliasKeys.indexOf(key)) return key
        for (let i = 0, aliasKey; (aliasKey = aliasKeys[i]) !== undefined; i++) {
          if (~(options.alias[aliasKey] || []).indexOf(key)) return aliasKey
        }
        return key
      })

      if (normalizedKeys.length < 1) return

      ui.div(__(groupName))

      // actually generate the switches string --foo, -f, --bar.
      const switches = normalizedKeys.reduce((acc, key) => {
        acc[key] = [ key ].concat(options.alias[key] || [])
          .map(sw => {
            // for the special positional group don't
            // add '--' or '-' prefix.
            if (groupName === self.getPositionalGroupName()) return sw
            else return (sw.length > 1 ? '--' : '-') + sw
          })
          .join(', ')

        return acc
      }, {})

      normalizedKeys.forEach((key) => {
        const kswitch = switches[key]
        let desc = descriptions[key] || ''
        let type = null

        if (~desc.lastIndexOf(deferY18nLookupPrefix)) desc = __(desc.substring(deferY18nLookupPrefix.length))

        if (~options.boolean.indexOf(key)) type = `[${__('boolean')}]`
        if (~options.count.indexOf(key)) type = `[${__('count')}]`
        if (~options.string.indexOf(key)) type = `[${__('string')}]`
        if (~options.normalize.indexOf(key)) type = `[${__('string')}]`
        if (~options.array.indexOf(key)) type = `[${__('array')}]`
        if (~options.number.indexOf(key)) type = `[${__('number')}]`

        const extra = [
          type,
          (key in demandedOptions) ? `[${__('required')}]` : null,
          options.choices && options.choices[key] ? `[${__('choices:')} ${
            self.stringifiedValues(options.choices[key])}]` : null,
          defaultString(options.default[key], options.defaultDescription[key])
        ].filter(Boolean).join(' ')

        ui.span(
          { text: kswitch, padding: [0, 2, 0, 2], width: maxWidth(switches, theWrap) + 4 },
          desc
        )

        if (extra) ui.div({ text: extra, padding: [0, 0, 0, 2], align: 'right' })
        else ui.div()
      })

      ui.div()
    })

    // describe some common use-cases for your application.
    if (examples.length) {
      ui.div(__('Examples:'))

      examples.forEach((example) => {
        example[0] = example[0].replace(/\$0/g, base$0)
      })

      examples.forEach((example) => {
        if (example[1] === '') {
          ui.div(
            {
              text: example[0],
              padding: [0, 2, 0, 2]
            }
          )
        } else {
          ui.div(
            {
              text: example[0],
              padding: [0, 2, 0, 2],
              width: maxWidth(examples, theWrap) + 4
            }, {
              text: example[1]
            }
          )
        }
      })

      ui.div()
    }

    // the usage string.
    if (epilogs.length > 0) {
      const e = epilogs.map(epilog => epilog.replace(/\$0/g, base$0)).join('\n')
      ui.div(`${e}\n`)
    }

    // Remove the trailing white spaces
    return ui.toString().replace(/\s*$/, '')
  }

  // return the maximum width of a string
  // in the left-hand column of a table.
  function maxWidth (table, theWrap, modifier) {
    let width = 0

    // table might be of the form [leftColumn],
    // or {key: leftColumn}
    if (!Array.isArray(table)) {
      table = Object.keys(table).map(key => [table[key]])
    }

    table.forEach((v) => {
      width = Math.max(
        stringWidth(modifier ? `${modifier} ${v[0]}` : v[0]),
        width
      )
    })

    // if we've enabled 'wrap' we should limit
    // the max-width of the left-column.
    if (theWrap) width = Math.min(width, parseInt(theWrap * 0.5, 10))

    return width
  }

  // make sure any options set for aliases,
  // are copied to the keys being aliased.
  function normalizeAliases () {
    // handle old demanded API
    const demandedOptions = yargs.getDemandedOptions()
    const options = yargs.getOptions()

    ;(Object.keys(options.alias) || []).forEach((key) => {
      options.alias[key].forEach((alias) => {
        // copy descriptions.
        if (descriptions[alias]) self.describe(key, descriptions[alias])
        // copy demanded.
        if (alias in demandedOptions) yargs.demandOption(key, demandedOptions[alias])
        // type messages.
        if (~options.boolean.indexOf(alias)) yargs.boolean(key)
        if (~options.count.indexOf(alias)) yargs.count(key)
        if (~options.string.indexOf(alias)) yargs.string(key)
        if (~options.normalize.indexOf(alias)) yargs.normalize(key)
        if (~options.array.indexOf(alias)) yargs.array(key)
        if (~options.number.indexOf(alias)) yargs.number(key)
      })
    })
  }

  // if yargs is executing an async handler, we take a snapshot of the
  // help message to display on failure:
  let cachedHelpMessage
  self.cacheHelpMessage = function () {
    cachedHelpMessage = this.help()
  }

  // given a set of keys, place any keys that are
  // ungrouped under the 'Options:' grouping.
  function addUngroupedKeys (keys, aliases, groups) {
    let groupedKeys = []
    let toCheck = null
    Object.keys(groups).forEach((group) => {
      groupedKeys = groupedKeys.concat(groups[group])
    })

    keys.forEach((key) => {
      toCheck = [key].concat(aliases[key])
      if (!toCheck.some(k => groupedKeys.indexOf(k) !== -1)) {
        groups[defaultGroup].push(key)
      }
    })
    return groupedKeys
  }

  function filterHiddenOptions (key) {
    return yargs.getOptions().hiddenOptions.indexOf(key) < 0 || yargs.parsed.argv[yargs.getOptions().showHiddenOpt]
  }

  self.showHelp = (level) => {
    const logger = yargs._getLoggerInstance()
    if (!level) level = 'error'
    const emit = typeof level === 'function' ? level : logger[level]
    emit(self.help())
  }

  self.functionDescription = (fn) => {
    const description = fn.name ? decamelize(fn.name, '-') : __('generated-value')
    return ['(', description, ')'].join('')
  }

  self.stringifiedValues = function stringifiedValues (values, separator) {
    let string = ''
    const sep = separator || ', '
    const array = [].concat(values)

    if (!values || !array.length) return string

    array.forEach((value) => {
      if (string.length) string += sep
      string += JSON.stringify(value)
    })

    return string
  }

  // format the default-value-string displayed in
  // the right-hand column.
  function defaultString (value, defaultDescription) {
    let string = `[${__('default:')} `

    if (value === undefined && !defaultDescription) return null

    if (defaultDescription) {
      string += defaultDescription
    } else {
      switch (typeof value) {
        case 'string':
          string += `"${value}"`
          break
        case 'object':
          string += JSON.stringify(value)
          break
        default:
          string += value
      }
    }

    return `${string}]`
  }

  // guess the width of the console window, max-width 80.
  function windowWidth () {
    const maxWidth = 80
    if (typeof process === 'object' && process.stdout && process.stdout.columns) {
      return Math.min(maxWidth, process.stdout.columns)
    } else {
      return maxWidth
    }
  }

  // logic for displaying application version.
  let version = null
  self.version = (ver) => {
    version = ver
  }

  self.showVersion = () => {
    const logger = yargs._getLoggerInstance()
    logger.log(version)
  }

  self.reset = function reset (localLookup) {
    // do not reset wrap here
    // do not reset fails here
    failMessage = null
    failureOutput = false
    usages = []
    usageDisabled = false
    epilogs = []
    examples = []
    commands = []
    descriptions = objFilter(descriptions, (k, v) => !localLookup[k])
    return self
  }

  let frozens = []
  self.freeze = function freeze () {
    let frozen = {}
    frozens.push(frozen)
    frozen.failMessage = failMessage
    frozen.failureOutput = failureOutput
    frozen.usages = usages
    frozen.usageDisabled = usageDisabled
    frozen.epilogs = epilogs
    frozen.examples = examples
    frozen.commands = commands
    frozen.descriptions = descriptions
  }
  self.unfreeze = function unfreeze () {
    let frozen = frozens.pop()
    failMessage = frozen.failMessage
    failureOutput = frozen.failureOutput
    usages = frozen.usages
    usageDisabled = frozen.usageDisabled
    epilogs = frozen.epilogs
    examples = frozen.examples
    commands = frozen.commands
    descriptions = frozen.descriptions
  }

  return self
}
