#!/usr/bin/env python

# std
import os
import functools
import sys

# ssl check
try:
    import ssl
except ImportError:
    ssl = None

# install checks
try:
    import tornado
except ImportError:
    print "Tornado is not installed but is required. Please run 'pip install tornado==2.2.1'"
    sys.exit(1)

try:
    import setproctitle
except ImportError:
    print "setproctitle is not installed but is required. Please run 'pip install setproctitle'"
    sys.exit(1)

try:
    from deiman import Deiman
except ImportError:
    print "deiman is not installed but is required. Please run 'pip install deiman'"
    sys.exit(1)

# Just in case some tit tries to run the file in /bin
try:
    from blackhole import __pname__, __fullname__
except ImportError:
    print "blackhole is not installed, please install it using the instructions in the README file"
    sys.exit(1)

# pip stuff
from tornado import ioloop
from tornado.options import options

# blackhole
from blackhole.opts import *
from blackhole.log import log
from blackhole.connection import connection_ready, sockets
from blackhole.ssl_utils import verify_ssl_opts, BlackholeSSLException,\
    sslkwargs
from blackhole.utils import setgid, setuid


if sys.version_info < (2, 5):
    print "blackhole requires Python 2.5 or greater"
    sys.exit(1)

setproctitle.setproctitle(__pname__)

tornado.options.parse_command_line()
if options.conf and os.path.exists(options.conf):
    tornado.options.parse_config_file(options.conf)

if options.ssl and not ssl:
    log.error("Unable to use SSL as SSL library is not compiled in")
    sys.exit(1)

if __name__ == "__main__":
    action = None
    for arg in sys.argv[1:]:
        if arg in ("--version", "-v"):
            print "Version:", __fullname__
            sys.exit(0)
        if not arg.startswith("--"):
            action = arg
    if action not in ('start', 'stop', 'status') or action is None:
        print_help()
        sys.exit(2)

    if len(sys.argv) == 1:
        print_help()
        sys.exit(2)

    if options.ssl:
        try:
            verify_ssl_opts()
        except BlackholeSSLException, e:
            log.error(e)
            sys.exit(1)
        # Override SSL options based on options passed in
        sslkwargs['keyfile'] = options.ssl_key
        sslkwargs['certfile'] = options.ssl_cert

    io_loop = ioloop.IOLoop.instance()

    # Iterate over the dictionary of socket connections
    # and add them to the IOLoop
    for _, sock in sockets().iteritems():
        callback = functools.partial(connection_ready, sock)
        io_loop.add_handler(sock.fileno(), callback, io_loop.READ)

    # Change group and user
    setgid()
    setuid()

    # Do the daemon actions
    d = Deiman(options.pid)
    if action == "start":
        d.start()
    elif action == "stop":
        d.stop()
        sys.exit(0)
    elif action == "status":
        d.status()
        sys.exit(0)

    try:
        io_loop.start()
    except KeyboardInterrupt, SystemExit:
        io_loop.stop()
        d.stop()
        sys.exit(0)
