'use strict'

const cli = require('heroku-cli-util')
const co = require('co')

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

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

  let topology = yield heroku.get(`/spaces/${spaceName}/topology`)
  let appInfo = []
  if (topology.apps) {
    appInfo = yield topology.apps.map((app) => heroku.get(`/apps/${app.id}`))
  }

  render(spaceName, topology, appInfo, context.flags)
}

function render (spaceName, topology, appInfo, flags) {
  if (flags.json) {
    cli.styledJSON(topology)
  } else {
    if (topology.apps) {
      topology.apps.forEach((app) => {
        let formations = []
        let dynos = []

        if (app.formations) {
          app.formations.forEach((formation) => {
            formations.push(formation.process_type)

            if (formation.dynos) {
              formation.dynos.forEach((dyno) => {
                let dynoS = [`${formation.process_type}.${dyno.number}`, dyno.private_ip, dyno.hostname].filter(Boolean)
                dynos.push(dynoS.join(' - '))
              })
            }
          })
        }

        let domains = app.domains.sort()
        formations = formations.sort()
        dynos = dynos.sort((a, b) => {
          let apt = getProcessType(a)
          let bpt = getProcessType(b)
          if (apt > bpt) {
            return 1
          } else if (apt < bpt) {
            return -1
          }

          return getProcessNum(a) - getProcessNum(b)
        })

        let info = appInfo.find((info) => info.id === app.id)
        let header = info.name
        if (formations.length > 0) {
          header += ` (${cli.color.cyan(formations.join(', '))})`
        }

        cli.styledHeader(header)
        cli.styledObject({
          Domains: domains,
          Dynos: dynos
        }, ['Domains', 'Dynos'])
        cli.log()
      })
    }
  }
}

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