#!/usr/bin/python3
""" Command-line interface to the Ombutel API """

import argparse
import json
import sys
import urllib.request, urllib.parse, urllib.error

MAINT_KEY_FILE = '/etc/ombutel/ombutel-maint.conf'

def error(string):
    """ Print an error message """
    print(string, file=sys.stderr)


def fatal(string):
    """ Fatal error and exit """
    error("Error: {}".format(string))
    error("Aborting")
    sys.exit(1)


def do_call(action, data, debug):
    """ A single API call. Returns the data on success """
    url = 'http://localhost/api/' + action
    data_str = urllib.parse.urlencode(data).encode('utf-8')
    if debug:
        error("About to call {}, data: <{}>".format(url, data_str))
    output = urllib.request.urlopen(url, data_str).read().decode('utf-8')
    if debug:
        error("Result: {}".format(output))
    result = json.loads(output)
    if 'status' not in result:
        fatal("Action {} failed: no status in output. Output: {}."
              .format(action, result))
    if result['status'] != 'success':
        if 'message' in result:
            message = result['message']
        else:
            message = "Missing error message for " + url + \
                      ". Programmer needed to throw an exception with " + \
                      "that errror message."
        fatal("Action: {}: status: {}. Message: {}.".format(action,
                                                            result['status'],
                                                            message))
    if 'data' not in result:
        return []
    return result['data']


def parse_args():
    """ Command-line arguments parser """
    parser = argparse.ArgumentParser()
    parser.add_argument('-c', '--compact', action='store_true',
                        help="Print output in a single line")
    parser.add_argument('-d', '--debug', action='store_true',
                        help="Dump raw requests and responses to stderr")
    parser.add_argument('-s', '--set', action='append',
                        help="set a POST variable")
    parser.add_argument('action', help="API action name")
    parser.add_argument('action_arg', nargs='?',
                        help="API action parameter")
    return parser.parse_args()


def main():
    """ Main function """
    query = {}
    args = parse_args()
    if args.set:
        for arg in args.set:
            var, val = arg.split('=', 2)
            query[var] = val

    if args.action_arg:
        address = "{}/{}".format(args.action, args.action_arg)
    else:
        address = args.action

    maint_key_str = open(MAINT_KEY_FILE).read().rstrip()
    res_auth = do_call('authenticate', {'key': maint_key_str}, args.debug)

    query['token'] = res_auth['token']
    res = do_call(address, query, args.debug)
    if args.compact:
        indent = None
        separators=(',  ', ': ')
    else:
        indent = 4
        separators=(',', ': ')
    print(json.dumps(res, indent=indent, sort_keys=True, separators=separators))


if __name__ == '__main__':
    main()
