#!/usr/bin/env node

'use strict'

const fs = require('fs')
const vm = require('vm')
const minimist = require('minimist')
const composer = require('../composer')

const argv = minimist(process.argv.slice(2), {
    string: ['apihost', 'auth', 'deploy', 'lower', 'entity', 'entities'],
    boolean: ['insecure', 'encode', 'json', 'version', 'quiet'],
    alias: { auth: 'u', insecure: 'i', version: 'v' }
})

if (argv.version) {
    console.log(composer.version)
    return
}

let count = 0
if (argv.json) count++
if (argv.encode) count++
if (argv.entity) count++
if (typeof argv.deploy !== 'undefined') count++

if (argv._.length !== 1 || count > 1 || argv.deploy === '' || argv.entity === '' || argv.entities === '') {
    console.error('Usage:')
    console.error('  compose composition.js[on] command [flags]')
    console.error('Commands:')
    console.error('  --json                 output the json representation for the composition (default command)')
    console.error('  --deploy NAME          deploy the composition with name NAME')
    console.error('  --entity NAME          output the conductor action definition for the composition (giving name NAME to the composition)')
    console.error('  --entities NAME        convert the composition into an array of action definition (giving name NAME to the composition)')
    console.error('  --encode               output the conductor action code for the composition')
    console.error('Flags:')
    console.error('  --lower [VERSION]      lower to primitive combinators or specific composer version')
    console.error('  --apihost HOST         API HOST')
    console.error('  -u, --auth KEY         authorization KEY')
    console.error('  -i, --insecure         bypass certificate checking')
    console.error('  -v, --version          output the composer version')
    console.error('  --quiet                omit detailed diagnostic messages')
    process.exit(127)
}

try {
    const filename = argv._[0]
    let source
    try {
        source = fs.readFileSync(filename, { encoding: 'utf8' })
    } catch (error) {
        console.error('File not found')
        if (!argv.quiet) console.log(error)
        process.exit(6)
    }
    let composition
    try {
        composition = filename.slice(filename.lastIndexOf('.')) === '.js' ? vm.runInNewContext(source, { composer, require, console, process }) : composer.deserialize(JSON.parse(source))
        if (typeof argv.lower === 'string') composition = composer.lower(composition, argv.lower)
    } catch (error) {
        console.error('Bad composition')
        if (!argv.quiet) console.log(error)
        process.exit(4)
    }
    if (argv.deploy) {
        const options = { ignore_certs: argv.insecure }
        if (argv.apihost) options.apihost = argv.apihost
        if (argv.auth) options.api_key = argv.auth
        return Promise.resolve()
            .then(() => composer.openwhisk(options).compositions.deploy(composer.composition(argv.deploy, composition), false))
            .then(obj => {
                const names = obj.actions.map(action => action.name)
                console.log(`ok: created action${names.length > 1 ? 's' : ''} ${names}`)
            })
            .catch(error => {
                if (error.constructor && error.constructor.name === 'OpenWhiskError') {
                    switch (error.statusCode) {
                        case 401:
                            console.error('Authentication failure')
                            if (!argv.quiet) console.log(error)
                            process.exit(2)
                        case 403:
                            console.error('Authorization failure')
                            if (!argv.quiet) console.log(error)
                            process.exit(3)
                    }
                }
                console.error('Server error')
                if (!argv.quiet) console.log(error)
                process.exit(5)
            })
    } else if (argv.encode) {
        console.log(composer.encode(composer.composition('anonymous', composition), false).actions.slice(-1)[0].action.exec.code)
    } else if (argv.entity) {
        console.log(JSON.stringify(composer.encode(composer.composition(argv.entity, composition), false).actions.slice(-1)[0], null, 4))
    } else if (argv.entities) {
        console.log(JSON.stringify(composer.encode(composer.composition(argv.entities, composition), false).actions, null, 4))
    } else {
        console.log(JSON.stringify(composition, null, 4))
    }
} catch (error) {
    console.error('Internal error')
    if (!argv.quiet) console.log(error)
    process.exit(1)
}
