#!/usr/bin/env python

__author__ = "Subhav Pradhan"

import os, sys
import argparse, ConfigParser
import socket, zmq, json
from chariot_runtime_libs import get_logger, get_node_address, mongo_connect, handle_action

def main():
    # Get python logger.
    logger = get_logger("chariot-dm")

    # Default zeromq port.
    ZMQ_PORT = 8000

    argParser = argparse.ArgumentParser()
    parserGroup = argParser.add_mutually_exclusive_group()
    
    parserGroup.add_argument("-c", 
                             "--configFile", 
                             help="CHARIOT configuration file to use.")
    
    parserGroup.add_argument("-s", 
                             "--simulatedDMName", 
                             help="Indicates simulated Deployment Manager (DM). Value represents unique DM/node name.")

    args = argParser.parse_args()

    if (args.simulatedDMName is None and args.configFile is None):
        argParser.print_help()
        argParser.exit()

    nodeName = None
    simulateDMActions = False
    mongoServer = None

    if (args.simulatedDMName is not None):
        logger.info ("Simulating Deployment Manager with name: " + args.simulatedDMName)
        simulateDMActions = True
        nodeName = args.simulatedDMName
        mongoServer = "localhost"
    else:
        if (os.path.isfile(args.configFile)):
            logger.info ("Non simulated usage so using configuration file: " + args.configFile)
            configParser = ConfigParser.ConfigParser()
            configParser.read(args.configFile)
            
            try:
                nodeName = configParser.get("Base", "NodeName")
                logger.info ("Using node name: " + nodeName)
            except ConfigParser.NoOptionError, ConfigParser.NoSectionError:
                nodeName = socket.gethostname()
                logger.info ("Node name cannot be extracted from configuration file. Using: " + nodeName)

            try:
                mongoServer = configParser.get("Services", "MongoServer")
                logger.info ("Using mongo server located on: " + mongoServer)
            except ConfigParser.NoOptionError, ConfigParser.NoSectionError:
                mongoServer = "localhost"
                logger.info ("Mongo server cannot be extracted from configuration file. Using: " + mongoServer)
        else:
            logger.error ("Cannot find configuration file.")
            sys.exit()

    client = None
    db = None

    logger.info ("Connecting to mongo server: " + mongoServer)
    client = mongo_connect(mongoServer)

    if client is not None:
        db = client["ConfigSpace"]
    else:
        logger.info ("MongoClient not constructed correctly")
        sys.exit()

    # Creating ZeroMQ context and server socket.
    zmq_context = zmq.Context()
    zmq_socket = zmq_context.socket(zmq.REP)

    # Get IP and port of host.
    addr, port = get_node_address(db, nodeName)

    # Connect to given address(stored in database) or default port.
    if (addr is not None and port is not None):
        logger.info ("Using address: " + str(addr) + " and port: " + int(port))
        zmq_socket.bind("tcp://%s:%d"%(str(addr), int(port)))
    elif (addr is not None and port is None):
        # If port is none, use default ZMQ_PORT.
        logger.info ("Using address: " + str(addr))
        zmq_socket.bind("tcp://%s:%d"%(str(addr),ZMQ_PORT))

    while True:
        # Receive action, which is a JSON document.
        logger.info ("Waiting for deployment action")
        action = zmq_socket.recv()
        zmq_socket.send("Received")
        action_json = json.loads(action)
        logger.info ("Received deployment action: " + action_json["action"] + " for process: " + action_json["process"])
        handle_action (db, json.loads(action), simulateDMActions, nodeName)

if __name__ == '__main__':
    main()
