"""Collect log from pushers with using TCP connection or ZMQ sockets."""

import time
import logging
import signal

from functools import partial

from tornado import ioloop
from tornado.options import define, options, parse_command_line
from logfollow import install
from logfollow.server import LogServer, LogTracer

def start():
    """Creqte objects of TCP and Websocket server and run it"""
    io_loop = ioloop.IOLoop.instance()

    io_loop.tcp_server = LogServer(io_loop=io_loop)
    io_loop.tcp_server.listen(options.gateway_port, options.gateway_host)
    logging.info('Start TCP server on %s:%s',
                 options.gateway_host, options.gateway_port)

    app = LogTracer(options)
    app.listen(options.port, address=options.host)
    logging.info('Start Websocket server on %s:%s',
                 options.host, options.port)

    # Starting infinite I/O loop
    io_loop.start()

def catch_signal(signal, frame):
    """Catcher for system signals
    
    In current application we will catch SIGTERM and SIGINT signals. 
    Last for e.g. will be generated by kernel after usage of ^C in TTY. 
    """
    logging.warning('Caught signal: %s', signal)
    ioloop.IOLoop.instance().add_callback(shutdown)

def shutdown():
    """Safely stop tornado IO loop by adding timeout for 
    sending responses to all allready connected clients"""
    io_loop = ioloop.IOLoop.instance()

    io_loop.tcp_server.stop()
    logging.info('Stopping TCP server')
    
    io_loop.add_timeout(time.time() + 2, io_loop.stop)
    logging.debug('IO loop will be stopped in 2 seconds ...')

define('debug', default=True, type=bool)
define('host', default='127.0.0.1', type=str)
define('port', default=8001, type=int)
define('gateway_host', default='127.0.0.1', type=str)
define('gateway_port', default=6777, type=int)
define('templates', default=install.STATIC_DIR, type=str)

if __name__ == '__main__':
    # Parse options from command lines
    parse_command_line()
    options.socket_handler = 'logs'

    # Catch termination signals
    signal.signal(signal.SIGTERM, catch_signal)
    signal.signal(signal.SIGINT, catch_signal)
    
    # Create TCP and HTTP server and run I/O loop
    start()