'use strict'

const cli = require('heroku-cli-util')
const co = require('co')
const strftime = require('strftime')
const _ = require('lodash')

const getProcessNum = (s) => parseInt(s.split('.', 2)[1])

function timeAgo (since) {
  let elapsed = Math.floor((new Date() - since) / 1000)
  let message = strftime('%Y/%m/%d %H:%M:%S %z', since)
  if (elapsed < 60) return `${message} (~ ${Math.floor(elapsed)}s ago)`
  else if (elapsed < 60 * 60) return `${message} (~ ${Math.floor(elapsed / 60)}m ago)`
  else if (elapsed < 60 * 60 * 25) return `${message} (~ ${Math.floor(elapsed / 60 / 60)}h ago)`
  else return message
}

function * run (context, heroku) {
  const spaceName = context.flags.space || context.args.space
  if (!spaceName) throw new Error('Space name required.\nUSAGE: heroku spaces:ps my-space')

  const [spaceDynos, space] = yield Promise.all([
    heroku.get(`/spaces/${spaceName}/dynos`),
    heroku.get(`/spaces/${spaceName}`)
  ])

  if (space.shield) {
    spaceDynos.forEach(spaceDyno => {
      spaceDyno.dynos.forEach(d => {
        if (d.size) {
          d.size = d.size.replace('Private-', 'Shield-')
        }
      })
    })
  }

  if (context.flags.json) {
    cli.styledJSON(spaceDynos)
  } else {
    render(spaceDynos)
  }
}

function render (spaceDynos) {
  _.forEach(spaceDynos, (spaceDyno) => {
    printDynos(spaceDyno.app_name, spaceDyno.dynos)
  })
}

function printDynos (appName, dynos) {
  let dynosByCommand = _.reduce(dynos, function (dynosByCommand, dyno) {
    let since = timeAgo(new Date(dyno.updated_at))
    let size = dyno.size || '1X'

    if (dyno.type === 'run') {
      let key = 'run: one-off processes'
      if (dynosByCommand[key] === undefined) dynosByCommand[key] = []
      dynosByCommand[key].push(`${dyno.name} (${size}): ${dyno.state} ${since}: ${dyno.command}`)
    } else {
      let key = `${cli.color.green(dyno.type)} (${cli.color.cyan(size)}): ${dyno.command}`
      if (dynosByCommand[key] === undefined) dynosByCommand[key] = []
      let state = dyno.state === 'up' ? cli.color.green(dyno.state) : cli.color.yellow(dyno.state)
      let item = `${dyno.name}: ${cli.color.green(state)} ${cli.color.dim(since)}`
      dynosByCommand[key].push(item)
    }
    return dynosByCommand
  }, {})
  _.forEach(dynosByCommand, function (dynos, key) {
    cli.styledHeader(`${appName} ${key} (${cli.color.yellow(dynos.length)})`)
    dynos = dynos.sort((a, b) => getProcessNum(a) - getProcessNum(b))
    for (let dyno of dynos) cli.log(dyno)
    cli.log()
  })
}

module.exports = {
  topic: 'spaces',
  command: 'ps',
  description: 'list dynos for a space',
  needsAuth: true,
  args: [{ name: 'space', optional: true, hidden: true }],
  flags: [
    { name: 'space', char: 's', hasValue: true, description: 'space to get dynos of' },
    { name: 'json', description: 'output in json format' }
  ],
  run: cli.command(co.wrap(run))
}
