#!/usr/bin/env python
import argparse
import inspect
import convertible
import insider.facade
import sys
import traceback
import logging
import httplib


def create_args_parser():
    parser = argparse.ArgumentParser(description='Syncloud insider maps port on router and creates DNS records')
    parser.add_argument('--bin-path', default=insider.facade.default_bin_path, dest='bin_path')
    parser.add_argument('--config-path', default=insider.facade.default_config_path, dest='config_path')
    parser.add_argument('--log-path', default=insider.facade.default_logs_path, dest='log_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")
    sub = subparsers.add_parser('service_info', help="service info")
    sub.add_argument('name', help="service 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):
    if debug:
        logging.basicConfig(level=logging.DEBUG)
        httplib.HTTPConnection.debuglevel = 1
    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__':
    parser = create_args_parser()
    args = parser.parse_args()

    facade = insider.facade.get_insider(args.bin_path, args.config_path, args.log_path)

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