#!/usr/bin/env python

import os
import sys
import time
import pprint
import signal
import socket
import logging
import optparse

import aimes.bundle

DEFAULT_BUNDLE_DBURL  = "mongodb://54.221.194.147:24242/"

        
# ------------------------------------------------------------------------------
#
def parse_options():

    parser = optparse.OptionParser (add_help_option=False)

    parser.add_option ('-c', '--config-file', dest='config_file', default=None)
    parser.add_option ('-m', '--mode',        dest='mode',        default='daemon') 
    parser.add_option ('-s', '--session-id',  dest='session_id',  default=None)
    parser.add_option ('-u', '--url',         dest='url',         default=DEFAULT_BUNDLE_DBURL) 
    parser.add_option ('-v', '--verbose',     dest='verbose',     action ='store_true') 
    parser.add_option ('-h', '--help',        dest='help',        action ='store_true') 

    return parser.parse_args()


# ------------------------------------------------------------------------------
#
def usage(msg=None):

    if msg:
        print "\n        ERROR  : %s" % msg

    print """
        usage  : %s -c <config> [-m <mode>] [-u url] [-v] [-h]
        example: %s -c bundle.cfg -m daemon -u mongodb://localhost/

        options:
            -c --config-file
                location of the bundle configuration file (mandatory)
           
            -m --mode
                specify connectivity mode: daemon or debug (default: daemon)
           
            -u --url
                specify communication endpoint for mongodb 
                default: %s

            -s --session-id
                specify a previous session id to reconnect to
           
            -v --verbose
                verbose operation (default: no)
           
            -h --help
                print help (default: no)


        modes:

            daemon: the bundle server will start agents according to the
                    config file, collect the information gathered by the
                    agents, and store it in a mongodb for later query by
                    clients.
            debug : the bundle server will start agents according to the
                    config file, collect the information gathered by the
                    agents, and print them on stdout.

            For daemon modes, the agent will got into background operation
            and will recollect live information from the agents every 60
            seconds, ie. it will become a dameon.


""" % (sys.argv[0], sys.argv[0], DEFAULT_BUNDLE_DBURL)

    if msg :
        sys.exit (-1)

    else :
        sys.exit (0)
        

# ------------------------------------------------------------------------------
#
def main(argv=None):

    options, args = parse_options()

    help         = options.help
    config_file  = options.config_file
    mode         = options.mode
    url          = options.url
    session_id   = options.session_id
    verbose      = options.verbose

    if help :
        usage ()

    if args :
        usage ("cannot handle arguments %s" % str(args))

    if not config_file:
        usage("config file not specified")

    # we need to make path to bundle config absolute (for daemon)
    config_file = os.path.abspath (config_file) 

    if mode not in ['daemon', 'debug'] :
        usage("mode '%s' not supported" % mode)

    if not os.path.isfile(config_file):
        usage("config file %s does not exist" % config_file)

    if verbose:
        logging.basicConfig(format='%(asctime)s %(levelname)s:%(name)s:%(filename)s:%(lineno)s:%(message)s',
            level=logging.DEBUG)
    else:
        logging.basicConfig(format='%(asctime)s %(levelname)s:%(name)s:%(filename)s:%(lineno)s:%(message)s',
            level=logging.ERROR)

    if mode == 'daemon' :
        try:
            import Pyro4
        except ImportError:
            logging.critical("Bundle Daemon depends on Pyro4: install Pyro4.")
            sys.exit(1)

        def sigint_handler(signum, frame):
            daemon.shutdown()
            bs.close()
            print "bundled: interrupt - AIMES.Bundle server session has terminated"
            sys.exit(0)

        bs = aimes.bundle.Session(database_url=url, uid=session_id, config_file=config_file)

        hostname = socket.getfqdn()
        daemon   = Pyro4.Daemon(host=hostname)
        uri      = str(daemon.register(bs))
        print "uri=", uri
        bs.publish_pyro_uri(uri)
        signal.signal(signal.SIGINT, sigint_handler)
        daemon.requestLoop()

    elif mode == 'debug' :
        print "Not supported yet"
        return
        # Note that this mode does not use the bundle api, but the
        # # implementation level API -- it mostly exists for debuggin purposes!
        # bm = aimes.bundle.impl.BundleManager()
        # bm.load_cluster_credentials(config_file)
        # ret = bm.get_data ()

        # for cluster in ret['cluster_list'] :
        #     print "===> %s" % cluster
        #     print
        #     print "--   config"
        #     pprint.pprint (ret['cluster_config'][cluster])
        #     print
        #     print "--   workload"
        #     pprint.pprint (ret['cluster_workload'][cluster])
        #     print
        #     print "--   bandwidth"
        #     pprint.pprint (ret['cluster_bandwidth'][cluster])
        #     print
        #     print

if __name__ == "__main__":
    
    sys.exit(main())
