#!/usr/bin/env python

from __future__ import absolute_import
from __future__ import print_function

import argparse
import logging
import socket
import threading
import signal
import itertools
import pdb

from speakeasy.speakeasy import Speakeasy

logger = logging.getLogger()
quit_event = threading.Event()


def init_logger(verbose):
    if verbose:
        logger.setLevel(logging.DEBUG)
    else:
        logger.setLevel(logging.INFO)
    formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
    handler = logging.StreamHandler()
    handler.setFormatter(formatter)
    logger.addHandler(handler)


def catch_quit_signal(signum, stack):
    logger.warn("Caught signal %d", signum)
    quit_event.set()


def main():
    parser = argparse.ArgumentParser(description='Run Speakeasy server')
    parser.add_argument('-H', '--host', required=False, default=socket.getfqdn(),
                        help='Hostname to emit metrics as')
    parser.add_argument('-ms', '--metric-socket', required=True,
                        help='Metric socket to listen on')
    parser.add_argument('-cp', '--cmd-port', required=True,
                        help='Port to receive commands on')
    parser.add_argument('-pp', '--pub-port', required=False,
                        help='Port to publish updates on')
    parser.add_argument('-e', '--emitter', required=True,
                        help='Module to emit data through periodically')
    parser.add_argument('-ea', '--emitter-args', required=False, nargs='*', action="append", default=[],
                        help='Arguments to be passed to emitter module')
    parser.add_argument('-ei', '--emission-interval', default=60, required=False, type=float,
                        help='Frequency to emit data (seconds)')
    parser.add_argument('-l', '--legacy', required=False, type=str,
                        help='Optional legacy socket to listen for incoming metrics')
    parser.add_argument('-sm', '--socket-mod', required=False, default=None, type=str,
                        help='File mode for metric socket')
    parser.add_argument('-v', '--verbose', required=False, default=False, action='store_true',
                        help='Enable verbose logging')

    args = parser.parse_args()

    init_logger(args.verbose)

    logger.info('Start speakeasy')

    socket_mod = int(args.socket_mod, base=8) if args.socket_mod else None
    server = Speakeasy(args.host, args.metric_socket, args.cmd_port,
                       args.pub_port, args.emitter, itertools.chain(*args.emitter_args),
                       args.emission_interval, args.legacy,
                       socket_mod=socket_mod)
    server.start()

    signal.signal(signal.SIGTERM, catch_quit_signal)
    signal.signal(signal.SIGINT, catch_quit_signal)
    signal.signal(signal.SIGPIPE, catch_quit_signal)
    signal.signal(signal.SIGUSR1, lambda x, y: pdb.set_trace())

    while not quit_event.is_set():
        try:
            quit_event.wait(10)
        except Exception as e:
            logger.info("Exception (%s)... exiting", e)

    server.shutdown()


if __name__ == '__main__':
    main()
