#!/usr/bin/env python

import argparse
import logging
import os
import sys
from sqlalchemy.exc import OperationalError
from threading import Thread
from time import sleep
import tornado.ioloop
import tornado.httpserver
import tornado.web

# Try to import raven so we can log exceptions to Sentry.
try:
    from raven.contrib.tornado import AsyncSentryClient
    raven_installed = True
except ImportError:
    raven_installed = False

import nsot
from nsot.app import Application
from nsot.settings import settings
from nsot.models import get_db_engine, Session
from nsot.util import get_loglevel, get_template_env


sa_log = logging.getLogger("sqlalchemy.engine.base.Engine")


def main(argv):

    parser = argparse.ArgumentParser(description="Network Source of Truth Web Server.")
    parser.add_argument("-c", "--config", default="/etc/nsot.yaml",
                        help="Path to config file.")
    parser.add_argument("-v", "--verbose", action="count", default=0, help="Increase logging verbosity.")
    parser.add_argument("-q", "--quiet", action="count", default=0, help="Decrease logging verbosity.")
    parser.add_argument("-V", "--version", action="version",
                        version="%%(prog)s %s" % nsot.__version__,
                        help="Display version information.")
    parser.add_argument("-p", "--port", type=int, default=None, help="Override port in config.")
    args = parser.parse_args()
    settings.update_from_config(args.config)

    log_level = get_loglevel(args)
    logging.basicConfig(
        level=log_level,
        format=settings.log_format,
    )

    if log_level < 0:
        sa_log.setLevel(logging.INFO)

    tornado_settings = {
        "static_path": os.path.join(os.path.dirname(nsot.__file__), "static"),
        "debug": settings.debug,
        "xsrf_cookies": True,
        "cookie_secret": settings.secret_key,
    }

    db_engine = get_db_engine(settings.database)
    Session.configure(bind=db_engine)

    my_settings = {
        "db_engine": db_engine,
        "db_session": Session,
        "template_env": get_template_env()
    }

    application = Application(my_settings=my_settings, **tornado_settings)

    # If Sentry DSN is set, try to import raven
    if settings.sentry_dsn:
        if not raven_installed:
            logging.warning(
                'Sentry DSN set but raven not installed. Not enabling Sentry.'
            )
        else:
            logging.info(
                'Sentry DSN set and raven installed. Enabling Sentry.'
            )
            application.sentry_client = AsyncSentryClient(settings.sentry_dsn)
    else:
        logging.info('Sentry DSN not set. Not enabling Sentry.')

    port = args.port or settings.port

    logging.info(
        "Starting application server with %d processes on port %d",
        settings.num_processes, port
    )

    server = tornado.httpserver.HTTPServer(application)
    server.bind(port, address=settings.bind_address)
    server.start()
    try:
        tornado.ioloop.IOLoop.instance().start()
    except KeyboardInterrupt:
        tornado.ioloop.IOLoop.instance().stop()
    finally:
        print "Bye"


if __name__ == "__main__":
    main(sys.argv)
