#!/usr/bin/env python
"""
    Author: John E. Vincent
	Email:	lusis.org+github.com@gmail.com
"""

import argparse
import pprint
import sys

from vogeler.client import VogelerClient
from vogeler.exceptions import VogelerClientException, VogelerPluginException
from vogeler.plugins import VogelerPlugin

import vogeler.logger as logger
import vogeler.conf as conf

pp = pprint.PrettyPrinter(indent=4)

def process_request(request):
    try:
        results = plugins.execute_plugin(request)
        c.message(results)
    except OSError, e:
        log.error("Unable to process request: %s" % request)
        c.message(plugins.get_last_error())
    except VogelerPluginException, e:
        log.error("Unable to process request: %s" % request)
        c.message(plugins.get_last_error())
    except Exception, e:
        raise

    if args.oneshot == True:
        log.warn("Oneshot requested. Running command %s and exiting" % request)
        shutdown()

def startup():
    c.monitor()

def shutdown():
    log.warn("Shutting down")
    c.close()
    return 0
    exit

def execute_run(*args, **kwargs):
    try:
        startup()
    except KeyboardInterrupt:
        shutdown()
    except Exception, e:
        raise 

def list_plugins(*args, **kwargs):
    try:
        if len(plugins.authorized_plugins) == 0:
            log.warn("No plugins are registered with the system")
        else:
            pp.pprint(plugins.plugin_registry)
    except Exception, e:
        log.fatal("Unable to list plugins")
        raise 

if __name__ == "__main__":
    appdesc = 'Vogeler client daemon'
    parser = argparse.ArgumentParser(description=appdesc)
    subparsers = parser.add_subparsers(help='commands')
    parser.add_argument('--plugin_dir', '-p',
                    help='Specifiy location of trusted plugins',
                    default=None,
                    required=False)
    parser.add_argument('--config', '-c',
                    help="Location of configuration file",
                    default=None,
                    required=False)
    parser.add_argument('--debug',
            help='Debug output',
            default = None,
            required=False)
    parser.add_argument('--verbose', '-v',
            help='Verbose output',
            default = None,
            required=False)
    parser.add_argument('--loglevel',
            help='Override log level',
            default = None,
            required=False)
    parser.add_argument('--qhost',
                    help='RabbitMQ server dsn',
                    default=None,
                    required=False)
    # runtime options
    runtime_parser = subparsers.add_parser('run', help='Runtime commands')
    runtime_parser.add_argument('--oneshot', '-o',
                    action="store_true",
                    default=False,
                    help='Exit after first command')
    runtime_parser.add_argument('--allow-unsafe', '-u',
                    action="store_true",
                    default=False,
                    help='WARNING: This options accepts any command that the client recieves. Use with caution!')
    runtime_parser.set_defaults(func=execute_run)

    # Noop options
    list_parser = subparsers.add_parser('list', help='List plugins')
    list_parser.set_defaults(func=list_plugins)

    args = parser.parse_args()

    if args.config is not None:
        try:
            local_config = conf.configure(cfg=args.config)
            if local_config.has_option('global', 'log_level'):
                log_level = local_config.get('global', 'log_level')
        except:
            raise
    else:
        log_level = 'WARN'

    if args.loglevel is not None:
        log_level = args.loglevel

    log = logger.LogWrapper(name='vogeler-client', level=log_level).logger()

    if args.qhost is not None:
        log.info("Using qhost from command-line options")
        mq = args.qhost
    elif args.config is not None and local_config.has_option('amqp' , 'dsn'):
        log.info("Using qhost from configuration file")
        mq = local_config.get('amqp', 'dsn')
    else:
        log.fatal("No qhost specified or no configuration file provided")
        sys.exit(0)

    if args.plugin_dir is not None:
        plugdir = args.plugin_dir
    elif args.config is not None and local_config.has_option('global', 'plugin_path'):
        plugdir = local_config.get('global', 'plugin_path')
    else:
        log.fatal("No plugin path provided")
        sys.exit(1)

    try:
        plugins = VogelerPlugin(plugin_dir=plugdir, loglevel=log_level)
        c = VogelerClient(callback_function=process_request, dsn=mq, loglevel=log_level)
    except Exception, e:
        raise

    args.func(args)

# vim: set ts=4 et sw=4 sts=4 sta filetype=python :
