#!/home/kura/.virtualenvs/blackhole-python2.7/bin/python

# std
import os
import functools
import sys
import signal

# 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==3.0'"
    sys.exit(1)

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

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

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

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

# Bypass tornado.options to print custom version
# and help message
from blackhole.opts import print_help
for arg in sys.argv[1:]:
    if arg in ("--version", "-v"):
        print "Version:", __fullname__
        sys.exit(0)
    if arg in ("--help", "-h"):
        print_help()
        sys.exit(0)

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

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

# 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, terminate, set_process_title

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__":
    signal.signal(signal.SIGTERM, terminate)
    action = None
    for arg in sys.argv[1:]:
        if not arg.startswith("--"):
            action = arg

    if action not in ('start', 'stop', 'status') or action is None:
        print_help()
        sys.exit(2)

    # Deprecated options check
    deprecated_opts()

    if options.debug:
        print """WARNING: Running with debug flag!\n"""\
              """This will generate a lots of disk I/O """\
              """and large log files"""

    d = Deiman(options.pid)
    if action == "stop":
        d.stop()
        sys.exit(0)
    elif action == "status":
        d.status()
        sys.exit(0)

    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

    # Grab the sockets early for multiprocessing
    sockets = sockets()
    if action == "start":
        d.start()
    else:
        sys.exit(0)

    # Change group and user
    setgid()
    setuid()

    # Set the custom process title of the master
    set_process_title()

     # Fork and create the ioloop
    options.workers = workers()
    tornado.process.fork_processes(options.workers)
    io_loop = ioloop.IOLoop.instance()

    # Set the custom process title of the workers
    set_process_title()

    # 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)

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