#!/usr/bin/env python
from os.path import normpath, abspath, join, dirname
import argparse
import inspect
import convertible
import insider.facade
import sys
import traceback


def create_args_parser():
    parser = argparse.ArgumentParser(description='Syncloud insider maps port on router and creates DNS records')
    parser.add_argument('--config-path', default='/etc/insider', dest='config_path')
    parser.add_argument('--debug', action='store_true')

    subparsers = parser.add_subparsers(help='available commands', dest='action')
    subparsers.add_parser('list_ports', help="list mapped ports")
    subparsers.add_parser('sync_all', help="sync port mappings and dns records")
    sub = subparsers.add_parser('add_service', help="add port mapping and DNS record for a service")
    sub.add_argument('name', help="name")
    sub.add_argument('protocol', help="for example: http or https")
    sub.add_argument('type', help="for example: _http._tcp")
    sub.add_argument('port', help="local port")
    sub.add_argument('url', help="url on server")
    sub = subparsers.add_parser('remove_service', help="remove port mapping and DNS record for a service")
    sub.add_argument('port', help="local port")
    subparsers.add_parser('cron_on', help="remove port mapping")
    subparsers.add_parser('cron_off', help="remove port mapping")
    sub = subparsers.add_parser('acquire_domain', help="acquire domain")
    sub.add_argument('email', help="email")
    sub.add_argument('password', help="password")
    sub.add_argument('user_domain', help="user domain")
    subparsers.add_parser('drop_domain', help="drop domain")
    subparsers.add_parser('full_name', help="shows device public name")

    # TODO: Ideally: config [set|get] section key value
    sub = subparsers.add_parser('set_redirect_info', help="set redirect info")

    sub.add_argument('domain', help="domain")
    sub.add_argument('api_url', help="api url")
    return parser


def call(func, kwargs):
    argspec = inspect.getargspec(func)
    params = kwargs
    if not argspec.keywords:
        params = dict()
        for key in kwargs.keys():
            if key in argspec.args:
                params[key] = kwargs.get(key)
    return func(**params)


def respond(result, message=None, success=True):
    response = dict(success=success, message=message, data=result)
    response_json = convertible.to_json(response)
    print(response_json)


def run(runner, debug):
    try:
        data = runner()
        respond(data)
    except Exception, e:
        if debug:
            print '-'*60
            traceback.print_exc(file=sys.stdout)
            print '-'*60

        respond(e, e.message, success=False)
        exit(1)

if __name__ == '__main__':
    app_path = normpath(abspath(join(dirname(__file__), '..')))

    parser = create_args_parser()
    args = parser.parse_args()

    config_path = args.config_path
    logs_path = join(app_path, 'log')
    facade = insider.facade.get_insider(app_path, config_path, logs_path)


    method = getattr(facade, args.action)
    run(lambda: call(method, vars(args)), args.debug)