#!/usr/bin/en python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from __future__ import division, absolute_import, print_function, unicode_literals

import datetime
import hashlib
import json
import os
import random
import sys
import time
import urllib
from urlparse import urlparse

import tornado.autoreload
import tornado.gen
import tornado.httpclient
import tornado.httpserver
import tornado.web
import tornado.websocket
from tornado.httputil import url_concat
from tornado.log import app_log as log
from tornado.options import define, options
from tornado.web import HTTPError

from mpin_utils.common import (
    detectProxy,
    getLogLevel,
    Keys,
    Seed,
    SIGNATURE_EXPIRES_OFFSET_SECONDS,
    signMessage,
    Time,
)
from mpin_utils import secrets
from storage import get_storage_cls
from dynamic_options import (
    generate_dynamic_options,
    process_dynamic_options,
)

from mobile_flow import MobileFlow

if os.name == "posix":
    from mpDaemon import Daemon
elif os.name == "nt":
    from mpWinService import Service as Daemon
else:
    raise Exception("Unsupported platform: {0}".format(os.name))


VERSION = '0.3'
BASE_DIR = os.path.dirname(__file__)
CONFIG_FILE = os.path.join(BASE_DIR, "config.py")
MOBILE_LOGIN_AUTHENTICATION_TIMEOUT_SECONDS = 10

PASS1_EXPIRES_TIME = 15
PERMITS_MIN, PERMITS_MAX = 7, 13


# OPTIONS

# general options
define("configFile", default=os.path.join(BASE_DIR, "config.py"), type=unicode)
define("address", default="127.0.0.1", type=unicode)
define("port", default=8011, type=int)
define("allowOrigin", default="*")
define("dynamicOptionsURL", default=None, type=unicode)

# debugging options
define("autoReload", default=False, type=bool)
define("logLevel", default="ERROR", type=unicode)

# time synchronization options
define("timePeriod", default=86400000, type=int)
define("syncTime", default=True, type=bool)

# security options
define("credentialsFile", default=os.path.join(BASE_DIR, "credentials.json"), type=unicode)
define("EntropySources", default="certivox:100", type=unicode)
define("seedValueLength", default=100, type=int)

# customer DTA service discovery options
define("DTALocalURL", default="", type=unicode)

# access number options
define("accessNumberExpireSeconds", default=300, type=int)
define("accessNumberExtendValiditySeconds", default=5, type=int)
define("accessNumberUseCheckSum", default=True, type=bool)

# authentication options
define("waitForLoginResult", default=False, type=bool)
define("VerifyUserExpireSeconds", default=3600, type=int)
define("maxInvalidLoginAttempts", default=3, type=int)
define("cacheTimePermits", default=True, type=bool)

# OTP options
define("requestOTP", default=False, type=bool)
define("OTTLength", default=16, type=int)

# RPA options
define("RPAVerifyUserURL", default="", type=unicode)
define("RPAPermitUserURL", default="", type=unicode)
define("RPAAuthenticateUserURL", default="", type=unicode)
define("RegisterForwardUserHeaders", default="", type=unicode)
define("LogoutURL", default="", type=unicode)

# PIN pad client options
define("rpsBaseURL", default="")
define("rpsPrefix", default="rps")
define("setDeviceName", default=False, type=bool)

# mobile client config
define("mobileUseNative", default=False, type=bool)
define("mobileConfig", default=None, type=list)
define("useNFC", default=False, type=bool)
define("serviceName", default="", type=unicode)
define("serviceType", default="online", type=unicode)
define("serviceIconUrl", default="", type=unicode)


# Mapping between local names of dynamic options and names from json
# in the form `remote_name`: `local_name`
# Only options that have mapping are processed
DYNAMIC_OPTION_MAPPING = {
    'time_synchronization': 'syncTime',
    'time_synchronization_period': 'timePeriod',
    'mobile_use_native': 'mobileUseNative',
    'mobile_client_config': 'mobileConfig',
}


# Dynamic options handlers
def handle_time_synchronization_update(updated, application, initial):

    log.debug("Handling time synchronization")
    if not any(x in updated for x in ('syncTime', 'timePeriod')) and not initial:
        log.debug("Nothing to do on time synchronization")
        return

    def _stop_scheduler():
            try:
                application.time_sync_scheduler.stop()
                log.debug("Stopped time sync schduler")
            except:
                pass
    if options.syncTime and (options.timePeriod > 0):
        _stop_scheduler()
        application.time_sync_scheduler \
            = tornado.ioloop.PeriodicCallback(
                Time.getTime,
                options.timePeriod,
                io_loop=application.io_loop)
        application.time_sync_scheduler.start()
        log.debug(
            "Started time sync schduler with period {0}"
            .format(options.timePeriod))
    else:
        _stop_scheduler()


# Convenience variable - list of dynamic options update handlers
DYNAMIC_OPTION_HANDLERS = [
    handle_time_synchronization_update,
]


# UTILITIES
def makeMPinID(userId, isMobile):
    endUserData = {
        "issued": str(Time.syncedNow()),
        "userID": userId,
        "mobile": int(isMobile or 0),
        "salt": os.urandom(16).encode("hex")
    }

    mpin_id = json.dumps(endUserData)

    return mpin_id.encode("hex")


def verifyToken(token):
    """A method for verifying the authentication token.

       n.b. The message variable should not be returned in a deployed application
    """
    successCode = int(token["successCode"])
    pinError = int(token["pinError"])

    # Get current time and token expired time
    expiresStr = token["expires"].replace(" ", "T").replace("Z", "")
    expiresTime = datetime.datetime.strptime(expiresStr, '%Y-%m-%dT%H:%M:%S')
    syncedTime = Time.syncedNow()

    # Check if token has expired.
    if syncedTime > expiresTime:
        fail = 1
        status = 401
        reason = "Authentication Failed. Token Expired."

    elif successCode != 0:
        if pinError == 0:  # No token.
            fail = 1
            status = 401
            reason = "Authentication Failed. Invalid Token."
        else:
            # Entering wrong PIN.
            fail = 1
            status = 401
            reason = "Authentication Failed. Invalid PIN."
    else:
        # Successful authentication
        fail = 0
        status = 200
        reason = "OK"

    return (fail, status, reason)


# BASE HANDLERS
class BaseHandler(tornado.web.RequestHandler):

    def set_default_headers(self):
        try:
            log.debug("Origin Header %s" % self.request.headers['Origin'])
            if self.request.headers['Origin'] in options.allowOrigin:
                self.set_header("Access-Control-Allow-Origin", self.request.headers['Origin'])
            elif "*" in options.allowOrigin:
                self.set_header("Access-Control-Allow-Origin", "*")
        except:
            log.debug("Origin header not defined")
        self.set_header("Access-Control-Allow-Credentials", "true")
        self.set_header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS")
        self.set_header("Access-Control-Allow-Headers", "Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, X-Requested-By, If-Modified-Since, X-File-Name, Cache-Control, WWW-Authenticate")

    def write_error(self, status_code, **kwargs):
        self.set_status(status_code, reason=self._reason)
        self.content_type = 'application/json'
        self.write({'version': VERSION, 'message': self._reason})

    def options(self, *args, **kwargs):
        self.set_status(200, reason="OK")
        self.content_type = 'application/json'
        self.write({'version': VERSION, 'message': "options request"})
        self.finish()
        return

    def finish(self, *args, **kwargs):
        if self._status_code == 401:
            self.set_header("WWW-Authenticate", "Authenticate")
        super(BaseHandler, self).finish(*args, **kwargs)

    @property
    def storage(self):
        return self.application.storage


class PrivateBaseHandler(BaseHandler):

    def prepare(self):
        # TODO: Check the remoteIP option
        # allow connections from whitelisted IP's
        # print self.request.remote_ip
        # self.set_status(404)
        # self.finish()
        pass


# PUBLIC HANDLERS
class ClientSettingsHandler(BaseHandler):
    def get(self):
        self.set_header("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate")
        self.set_header("Pragma", "no-cache")
        self.set_header("Expires", "Sat, 26 Jul 1997 05:00:00 GMT")

        baseURL = "{0}/{1}".format(options.rpsBaseURL, options.rpsPrefix.strip("/"))
        params = {
            "certivoxURL": Keys.certivoxServer(),
            "signatureURL": "{0}/signature".format(baseURL),
            "registerURL": "{0}/user".format(baseURL),
            "timePermitsURL": "{0}/timePermit".format(baseURL),
            "timePermitsStorageURL": "{0}".format(Keys.timePermitsStorageURL),
            "setupDoneURL": "{0}/setupDone".format(baseURL),
            "mpinAuthServerURL": baseURL,
            "authenticateURL": options.RPAAuthenticateUserURL,
            "mobileAuthenticateURL": "{0}/authenticate".format(baseURL),
            "setDeviceName": options.setDeviceName,
            "accessNumberUseCheckSum": options.accessNumberUseCheckSum,

            "appID": Keys.app_id,
            "requestOTP": options.requestOTP,
            "seedValue": secrets.generate_random_number(
                self.application.server_secret.rng, options.seedValueLength),

            "useWebSocket": False,

            "accessNumberDigits": 7 if options.accessNumberUseCheckSum else 6,
            "cSum": 1,
            "useNFC": options.useNFC,
        }

        if not options.requestOTP:
            params["accessNumberURL"] = "{0}/access".format(baseURL)
            params["getAccessNumberURL"] = "{0}/getAccessNumber".format(baseURL)

        if options.mobileUseNative:
            params["getQrUrl"] = "{0}/getQrUrl".format(baseURL)
            params["codeStatusURL"] = "{0}/codeStatus".format(baseURL)

        self.write(params)
        self.finish()


class RPSUserHandler(BaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def put(self, mpinId):

        try:
            data = json.loads(self.request.body)
            mobile = int(data.get("mobile", "0"))
            userId = data.get("userId")
            deviceName = data.get("deviceName", "")
            oldRegOTT = data.get("regOTT")

            if not userId:
                log.error("Missing userId")
                log.debug(self.request.body)
                self.set_status(400, reason="BAD REQUEST. INVALID USERID")
                self.finish()
                return

        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return

        if mpinId.strip("/"):
            mpinId = mpinId.strip("/")
            log.debug("Reactivation request for mpinId: {0}".format(mpinId))

            updateItem = self.storage.find(stage="register", mpinId=mpinId)
            if not updateItem:
                mpinId = None
                oldRegOTT = None
                log.error("Missing or invalid mpinID. Will generate a new mpinID")

            elif updateItem.regOTT != oldRegOTT:
                log.error("Missing or invalid regOTT")
                log.debug(self.request.body)
                self.set_status(400, reason="BAD REQUEST. INVALID REGOTT")
                self.finish()
                return

        if not mpinId:
            # Generate new mpinID
            updateItem = None
            mpinId = makeMPinID(userId, mobile)
            log.debug("New mpinID generated for user {0}: {1}".format(userId, mpinId))

        userData = data.get("userData")

        # Verify user >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

        # Generate activateKey
        regOTT = oldRegOTT or secrets.generate_ott(options.OTTLength, self.application.server_secret.rng, "hex")
        activateKey = signMessage("{0}{1}".format(mpinId, regOTT), Keys.app_key)
        nowTime = Time.syncedNow()
        expireTime = nowTime + datetime.timedelta(seconds=options.VerifyUserExpireSeconds)

        requestBody = json.dumps({
            "userId": userId,
            "mpinId": mpinId,
            "mobile": mobile,
            "activateKey": activateKey,
            "expireTime": Time.DateTimeToISO(expireTime),
            "resend": bool(updateItem),
            "deviceName": deviceName,
            "userData": userData or ""
        })

        if updateItem:
            updateItem.delete()

        client = tornado.httpclient.AsyncHTTPClient()

        pr = urlparse(self.request.full_url())
        base_url = "{0}://{1}".format(pr.scheme, pr.netloc)

        headers = {
            "RPS-BASE-URL": base_url
        }

        # Forward headers to the RPA
        if options.RegisterForwardUserHeaders:
            allHeaders = options.RegisterForwardUserHeaders == "*"
            rHeaders = map(lambda x: x.strip().lower(), options.RegisterForwardUserHeaders.split(","))
            for h in self.request.headers:
                if allHeaders or (h.lower() in rHeaders):
                    headers[h] = self.request.headers[h]

        RPAVerifyUserURL = options.RPAVerifyUserURL

        if not RPAVerifyUserURL:
            log.error("RPAVerifyUserURL option not set! Unable to make Verify request")
            self.set_status(400, "RPAVerifyUserURL option not set.")
            self.finish()
            return

        # Make the verify request to the RPA
        response = yield tornado.gen.Task(client.fetch, RPAVerifyUserURL, method="POST", headers=headers, body=requestBody)

        if response.error:
            log.error("RPA verify request error: {0}. Code: {1}, Reason: {2}".format(response.error, response.code, response.reason))
            error = response.code
            if error >= 500:
                error = 500

            self.set_status(error)
            self.finish()
            return

        forceActivate = False
        if response.body:
            try:
                responseData = json.loads(response.body)
                forceActivate = responseData.get("forceActivate", forceActivate)
            except:
                log.error("RPA verify request: Invalid JSON response: {0}".format(response.body))
                self.set_status(500)
                self.finish()
                return

        if forceActivate:
            log.debug("RPA response: force_activate. Activating UserID: {0}".format(userId))

        if forceActivate:
            active = activateKey
        else:
            active = 0

        log.debug("New regOTT generated: {0}. ForceActivate: {1}".format(regOTT, forceActivate))

        self.storage.add(
            expire_time=expireTime,
            stage="register",
            mpinId=mpinId,
            regOTT=regOTT,
            active=active
        )

        # Response to the client
        responseData = {
            "mpinId": mpinId,
            "regOTT": regOTT,
            "expireTime": expireTime.isoformat(),
            "nowTime": nowTime.isoformat(),
            "active": forceActivate
        }

        self.write(responseData)
        self.finish()


class RPSSignatureHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self, mpinId):

        regOTT = self.get_argument("regOTT")

        log.debug("ClientSecret request for mpinID: {0}".format(mpinId))

        mpinData = json.loads(mpinId.decode("hex"))
        mobile = mpinData.get("mobile", 0)

        I = self.storage.find(stage="register", mpinId=mpinId)
        if not I:
            log.debug("MpinID {0} not found.".format(mpinId))
            self.set_status(400, "M-Pin ID not found.")
            self.finish()
            return

        # Verify regOTT
        if I.regOTT != regOTT:
            log.error("MpinID {0} regOTT does not match!".format(mpinId))
            I.delete()
            self.set_status(400, "M-Pin ID not found.")
            self.finish()
            return

        # Verify Activated
        if I.active != signMessage("{0}{1}".format(mpinId, regOTT), Keys.app_key):
            log.debug("MpinID {0} is not activated!".format(mpinId))
            self.set_status(401, "M-PinID not active.")
            self.finish()
            return

        # Get hash of M-PIN ID
        hash_mpin_id_hex = hashlib.sha256(mpinId.decode("hex")).hexdigest()

        # Get hash of UserID ID
        hash_user_id = hashlib.sha256('{user_id}{salt}'.format(
            user_id=mpinData['userID'],
            salt=hashlib.sha256(self.application.server_secret.server_secret).hexdigest(),
        )).hexdigest()

        # Generate signed params
        path = "clientSecret"
        expires = Time.syncedISO(seconds=SIGNATURE_EXPIRES_OFFSET_SECONDS)
        hash_user_id = ""
        M = str("%s%s%s%s%s" % (path, Keys.app_id, hash_mpin_id_hex, hash_user_id, expires))
        signature_hex = signMessage(M, Keys.app_key)

        param_values = {
            'app_id': Keys.app_id,
            'expires': expires,
            'hash_mpin_id': hash_mpin_id_hex,
            'hash_user_id': hash_user_id,
            'mobile': mobile,
            'signature': signature_hex,
        }

        url = "{0}/{1}".format(options.DTALocalURL.rstrip("/"), path)
        urlParams = url_concat(url, param_values)

        client = tornado.httpclient.AsyncHTTPClient()
        response = yield tornado.gen.Task(client.fetch, urlParams, method="GET")

        if response.error:
            log.error("DTA clientSecret failed, URL: {0}. Code: {1}, Reason: {2}".format(urlParams, response.code, response.reason))
            self.set_status(500)
            self.finish()
            return

        if response.body:
            try:
                responseData = json.loads(response.body)
                clientSecretShare = responseData["clientSecret"]
            except:
                log.error("DTA /clientSecret Failed. Invalid JSON response".format(response.body))
                self.set_status(500)
                self.finish()
                return

        I.delete()

        params = urllib.urlencode(param_values)
        data = {
            "params": params,
            "clientSecretShare": clientSecretShare
        }

        self.write(data)
        self.finish()


class RPSTimePermitHandler(BaseHandler):

    def __init__(self, *args, **kwargs):
        super(RPSTimePermitHandler, self).__init__(*args, **kwargs)
        self.http_client = tornado.httpclient.AsyncHTTPClient()

    @tornado.gen.coroutine
    def get_time_permits(self, hash_mpin_id_hex, signature):
        # Get time permit from the local D-TA
        url = url_concat(
            "{0}/{1}".format(options.DTALocalURL.rstrip("/"), "timePermits"), {
                'hash_mpin_id': hash_mpin_id_hex,
                'signature': signature,
                'count': random.randint(PERMITS_MIN, PERMITS_MAX) if options.cacheTimePermits else 1})
        response = yield self.http_client.fetch(url)

        if response.error:
            log.error("DTA timePermit failed, URL: {0}. Code: {1}, Reason: {2}".format(url, response.code, response.reason))
            raise HTTPError(500)

        if response.body:
            try:
                response_data = json.loads(response.body)
                raise tornado.gen.Return(response_data["timePermits"])
            except (ValueError, KeyError):
                log.error("DTA /timePermit Failed. Invalid JSON response".format(
                    response.body))
                raise HTTPError(500)

    def cache_time_permits(self, time_permits, hash_mpin_id_hex):
        # Cache them in storage
        for date_epoch, time_permit in time_permits.iteritems():
            try:
                date_epoch = int(date_epoch)
            except ValueError:
                log.error("DTA /timePermit Failed. Date invalid integer")
                raise HTTPError(500)

            self.storage.add(
                expire_time=datetime.datetime.fromtimestamp(date_epoch * 60 * 1440) + datetime.timedelta(days=1),
                time_permit_id=hash_mpin_id_hex,
                time_permit_date=date_epoch,
                time_permit=time_permit)

    @tornado.gen.coroutine
    def get_time_permit(self, hash_mpin_id_hex, date_epoch, signature):
        """Get time permit from cache or request new."""
        if options.cacheTimePermits:
            time_permit_item = self.storage.find(time_permit_id=hash_mpin_id_hex, time_permit_date=date_epoch)
            if time_permit_item:
                # Get time permit from cache
                raise tornado.gen.Return(time_permit_item.time_permit)

        # No cached time permits for this mpin id, request new from D-TA
        time_permits = yield self.get_time_permits(hash_mpin_id_hex, signature)
        if options.cacheTimePermits:
            self.cache_time_permits(time_permits, hash_mpin_id_hex)

        # Return the one for today
        if str(date_epoch) not in time_permits:
            log.error("DTA /timePermit Failed. No time permit for today")
            raise HTTPError(500)
        raise tornado.gen.Return(time_permits[str(date_epoch)])

    @tornado.gen.coroutine
    def get(self, mpin_id):
        # Check revocation status of mpin id.
        if options.RPAPermitUserURL:
            response = yield self.http_client.fetch(
                url_concat(options.RPAPermitUserURL, {"mpin_id": mpin_id}),
                raise_error=False)

            if response.code != 200:
                # RPA rejects this mpin id
                raise HTTPError(response.code)

        hash_mpin_id_hex = hashlib.sha256(mpin_id.decode("hex")).hexdigest()
        today_epoch = secrets.today()
        signature = signMessage(hash_mpin_id_hex, Keys.app_key)
        time_permit = yield self.get_time_permit(hash_mpin_id_hex, today_epoch, signature)

        self.set_header("Cache-Control", "no-cache")
        self.finish({
            "date": today_epoch,
            "signature": signature,
            "storageId": hash_mpin_id_hex,
            'message': "M-Pin Time Permit Generated",
            'timePermit': time_permit,
            'version': VERSION,
        })


class RPSSetupDoneHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self, mpinId):
        log.debug("Setup done for mpinId: {0}".format(mpinId))
        self.set_status(200)
        self.finish()


class RPSGetAccessNumberHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        # Generate request for MPinWIDServer for WID
        wId = secrets.generate_random_webid(self.application.server_secret.rng, options.accessNumberUseCheckSum)

        while wId is None or (self.storage.find(stage="auth", wid=wId)):
            if wId is None:
                log.debug("WebId is None".format(wId))
            else:
                log.debug("WebId {0} already exists. Generating a new one".format(wId))
            wId = secrets.generate_random_webid(self.application.server_secret.rng, options.accessNumberUseCheckSum)

        log.debug("New webId generated: {0}." .format(wId))

        webOTT = secrets.generate_ott(options.OTTLength, self.application.server_secret.rng, "hex")

        nowTime = Time.syncedNow()
        expirePinPadTime = nowTime + datetime.timedelta(seconds=options.accessNumberExpireSeconds)
        expireTime = expirePinPadTime + datetime.timedelta(seconds=options.accessNumberExtendValiditySeconds)

        self.storage.add(stage="auth", expire_time=expireTime, webOTT=webOTT, wid=wId)

        params = {
            "ttlSeconds": options.accessNumberExpireSeconds,
            "accessNumber": wId,
            "webOTT": webOTT,
            "localTimeStart": Time.DateTimetoEpoch(nowTime),
            "localTimeEnd": Time.DateTimetoEpoch(expirePinPadTime)
        }

        self.write(params)
        self.finish()


class RPSGetQrUrlHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        mobileFlow = MobileFlow(self.application, self.storage)
        params = mobileFlow.generate_qr(mobileFlow.generate_wid())

        self.write(params)
        self.finish()


class RPSAccessHanler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        try:
            data = json.loads(self.request.body)
            webOTT = data["webOTT"]
        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return

        params = MobileFlow(self.application, self.storage).get_app_status(webOTT)

        self.write(params)
        self.finish()


class RPSAuthenticateHandler(BaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        try:
            data = json.loads(self.request.body)
            data = data["mpinResponse"]
            authOTT = data["authOTT"]
        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return
        except KeyError:
            log.error("Invalid JSON data structure")
            log.debug(data)
            self.set_status(400, reason="BAD REQUEST. INVALID DATA")
            self.finish()
            return

        I = self.storage.find(stage="auth", authOTT=authOTT)

        if not I:
            log.error("Invalid or expired authOTT")
            status = 412
            message = "Invalid or expired access number"
            userId = ""
            mpinId = ""
            response = {"message": message}

        else:
            authToken = I.authToken
            mpinId = authToken["mpin_id"].encode("hex")
            identity = json.loads(authToken["mpin_id"])
            userId = identity["userID"]

            (fail, status, reason) = verifyToken(authToken)

            aI = self.storage.find(stage="attempts", mpinId=mpinId)
            attemptsCount = aI and aI.attemptsCount or 0
            if attemptsCount >= options.maxInvalidLoginAttempts:
                fail = 1

            if fail == 0:
                # Delete invalid login attempts if any
                if aI:
                    aI.delete()

                # Authentication successful
                message = "Authentication successful"

                # Wait for browser authentication and get Logout information
                I.update(status=status, message=message)

                main_loop = tornado.ioloop.IOLoop.instance()

                # Wait until the browser is ready or timeout occurs
                timeOut = Time.syncedNow(seconds=MOBILE_LOGIN_AUTHENTICATION_TIMEOUT_SECONDS)
                while (not I.browserReady) and (Time.syncedNow() < timeOut):
                    yield tornado.gen.Task(main_loop.add_timeout, time.time() + 1)

                # Get the new status. Status can be changed with the /loginResult request
                if status != I.status:
                    status = I.status
                    message = I.message
                    response = {"message": message}

                elif I.browserReady:
                    logoutURL = I.logoutURL or ""
                    logoutData = I.logoutData or ""
                    response = {"logoutURL": logoutURL, "logoutData": logoutData}
                else:
                    # Timeout occured
                    status = 408
                    message = "Authentication timed out"
                    response = {"message": message}

            else:
                attemptsCount += 1
                if aI:
                    aI.update(attemptsCount=attemptsCount)
                else:
                    self.storage.add(stage="attempts", mpinId=mpinId, attemptsCount=attemptsCount)

                if attemptsCount >= options.maxInvalidLoginAttempts:
                    status = 410

                log.debug("Wrong PIN for user {0}.".format(userId))
                message = "Wrong PIN."
                response = {"message": message}
                I.update(status=status, message=message)

        self.set_status(status, message)
        self.write(response)
        self.finish()


class StatusHandler(BaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        reason = "active"
        self.set_status(200, reason=reason)
        self.write({'version': VERSION, 'message': reason})

        self.finish()


class ServiceHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        params = {
            "name": options.serviceName,
            "url": options.rpsBaseURL,
            "type": options.serviceType,
            "rps_prefix": options.rpsPrefix,
            "icon_url": options.serviceIconUrl,
        }

        self.write(params)
        self.finish()


class DefaultHandler(BaseHandler):
    def get(self, input):
        reason = "URI NOT FOUND"
        self.set_status(404, reason=reason)
        self.write({'version': VERSION, 'service_name': 'M-Pin authentication server', 'message': reason})
        return

    def post(self, input):
        reason = "URI NOT FOUND"
        self.set_status(404, reason=reason)
        self.write({'version': VERSION, 'service_name': 'M-Pin authentication server', 'message': reason})
        return

    def put(self, input):
        reason = "URI NOT FOUND"
        self.set_status(404, reason=reason)
        self.write({'version': VERSION, 'service_name': 'M-Pin authentication server', 'message': reason})
        return

    def delete(self, input):
        reason = "URI NOT FOUND"
        self.set_status(404, reason=reason)
        self.write({'version': VERSION, 'service_name': 'M-Pin authentication server', 'message': reason})
        return


# AUTHENTICATION HANDLER
class Pass1Handler(BaseHandler):
    """
    ..  apiTextStart

    *Description*

      Implements the first pass of the M-Pin Protocol

    *URL structure*

      ``/pass1``

    *Version*

      0.3

    *HTTP Request Method*

      POST

    *Request Data*

      JSON request::

        {
          "mpin_id":  "7b22...227d",
          "U":    "0409...3d9c",
          "UT":   "0402...d1d1",
          "pass" : 1
        }

      mpin_id is the hex encoded M-Pin ID, U is x.hash(mpin_id) and UT is
      x.(hash(mpin_id) + hash(data||hash(mpin_id)))

    *Returns*

      JSON response::

        {
          "y" : "212a...8d08",
          "version" : "0.3",
          "message" : "OK",
          "pass" : 1
        }

      y  is a 256 bit random value.

    *Status-Codes and Response-Phrases*

      ::

        Status-Code          Response-Phrase

        200                  OK
        403                  Invalid data received. <argument> argument missing
        403                  Invalid data received. No JSON object could be decoded
        403                  Invalid data received. Non-hexadecimal digit found
        500                  Failed to generate y
        500                  Failed to add pass one to memory

    ..  apiTextEnd

    """
    def post(self):
        # Remote request information
        if 'User-Agent' in self.request.headers.keys():
            UA = self.request.headers['User-Agent']
        else:
            UA = 'unknown'
        request_info = '%s %s %s %s ' % (self.request.path, self.request.remote_ip, UA, Time.syncedISO())

        try:
            receive_data = tornado.escape.json_decode(self.request.body)
            mpin_id = receive_data['mpin_id'].decode("hex")
            ut_hex = receive_data['UT']
            u_hex = receive_data['U']
        except KeyError as ex:
            reason = "Invalid data received. %s argument missing" % ex.message
            log.error("%s %s" % (request_info, reason))
            self.set_status(403, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        except (ValueError, TypeError) as ex:
            reason = "Invalid data received. %s" % ex.message
            log.error("%s %s" % (request_info, reason))
            self.set_status(403, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        log.debug("%s %s" % (request_info, receive_data))

        # Server generates Random number Y and sends it to Client
        try:
            y_hex = self.application.server_secret.get_pass1_value()
        except secrets.SecretsError as e:
            log.error(e.message)
            self.set_status(500, reason=e.message)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': e.message})
            self.finish()
            return

        # Store Pass1 values
        self.storage.add(
            expire_time=Time.syncedISO(seconds=PASS1_EXPIRES_TIME),
            stage="pass1",
            mpinId=mpin_id.encode('hex'),
            ut=ut_hex,
            u=u_hex,
            y=y_hex,
        )

        log.info("%s Stored Pass1 values" % request_info)

        reason = "OK"
        self.set_status(200, reason=reason)
        self.content_type = 'application/json'
        return_data = {
            'version': VERSION,
            'y': y_hex,
            'pass': 1,
            'message': reason
        }
        log.debug("%s %s" % (request_info, return_data))
        self.write(return_data)
        self.finish()
        return


class Pass2Handler(BaseHandler):
    """
    ..  apiTextStart

    *Description*

      Implements the second pass of the M-Pin Protocol. The result will be the authOTP.
      At this point the authentication token has also been written to the RPS.
      An authOTT will always be returned even if authentication fails.

    *URL structure*

      ``/pass2``

    *Version*

      0.3

    *HTTP Request Method*

      POST

    *Request Data*

      JSON request::

        {
          "WID" : "123456"
          "V" : "0411...05f6a",
          "pass" : 2,
          "OTP" : <1||0>
        }

      WID is web identifier used for mobile authentication
      When OTP is set to one this indicates that the radius OTP should be
      generated.  V is a parameter used to perform the final step of the M-Pin
      algorithm.

    *Returns*

      JSON response::

        {
          "OTP": "155317",
          "authOTT": "31ba0ed5efb75d91ef69a2b7eb1d3a26",
          "pass": 2,
          "version": "0.3"
        }

      OTP is the radius one time password. authOTT is the password used to log into the
      Customer's website.

    *Status-Codes and Response-Phrases*

      ::

        Status-Code          Response-Phrase

        200                  OK
        403                  Invalid data received. <argument> argument missing
        403                  Invalid data received. No JSON object could be decoded
        403                  Invalid data received. Non-hexadecimal digit found
        500                  Pass one data is not in memory

    ..  apiTextEnd

    """
    @tornado.gen.coroutine
    def post(self):
        # Remote request information
        if 'User-Agent' in self.request.headers.keys():
            UA = self.request.headers['User-Agent']
        else:
            UA = 'unknown'
        request_info = '%s %s %s %s ' % (self.request.path, self.request.remote_ip, UA, Time.syncedISO())

        try:
            receive_data = tornado.escape.json_decode(self.request.body)
            mpin_id_hex = receive_data['mpin_id']
            mpin_id = mpin_id_hex.decode('hex')
            WID = receive_data['WID']
            OTPEn = receive_data['OTP']
            v_data = receive_data['V'].decode("hex")
        except KeyError as ex:
            reason = "Invalid data received. %s argument missing" % ex.message
            log.error("%s %s" % (request_info, reason))
            self.set_status(403, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        except (ValueError, TypeError) as ex:
            reason = "Invalid data received. %s" % ex.message
            log.error("%s %s" % (request_info, reason))
            self.set_status(403, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        log.debug("%s %s" % (request_info, receive_data))

        # Get pass one values
        pass1Value = self.storage.find(stage="pass1", mpinId=mpin_id_hex)

        if pass1Value:
            u = pass1Value.u.decode("hex")
            ut = pass1Value.ut.decode("hex")
            y = pass1Value.y.decode("hex")
        else:
            reason = "Invalid pass one data"
            log.error("%s %s" % (request_info, reason))
            self.set_status(500, reason=reason)
            self.content_type = 'application/json'
            self.write({'version': VERSION, 'message': reason})
            self.finish()
            return
        log.info("%s loaded Pass1 values" % request_info)

        # Generate OTP value
        if int(OTPEn) == 1:
            OTP = "{0:06d}".format(
                secrets.generate_otp(self.application.server_secret.rng))
        else:
            OTP = '0'

        log.info("%s generate OTP" % request_info)

        successCode = self.application.server_secret.validate_pass2_value(
            mpin_id, u, ut, y, v_data)

        pinError = 0
        pinErrorCost = 0

        # Authentication Token expiry
        expires = Time.syncedISO(seconds=SIGNATURE_EXPIRES_OFFSET_SECONDS)

        # Form Authentication token
        token = {
            "mpin_id": mpin_id,
            "mpin_id_hex": mpin_id_hex,
            "successCode": successCode,
            "pinError": pinError,
            "pinErrorCost": pinErrorCost,
            "expires": expires,
            "WID": WID,
            "OTP": OTP
        }
        log.debug("%s M-Pin Auth token: %s" % (request_info, token))

        # Form authentication 128 hex encoded One Time Password
        authOTT = secrets.generate_auth_ott(self.application.server_secret.rng)

        # Form message to return to client #
        return_data = {
            'version': VERSION,
            'pass': 2,
            'authOTT': authOTT
        }

        if int(OTPEn) == 1:
            return_data['OTP'] = OTP

        if WID != "0":
            # Login with mobile
            I = self.storage.find(stage="auth", wid=WID)

            wid_flow = "wid"
            flow = "mobile"

            # if not I:
            #     log.error("Invalid or expired access number: {0} for mpinid: {1}".format(WID, mpinId))
            #     self.set_status(412, reason="INVALID OR EXPIRED ACCESS NUMBER")
            #     self.finish()
            #     return

            if I:
                I.update(authOTT=authOTT, mpinid=mpin_id, authToken=token)

        else:
            wid_flow = "browser"

            if int(token.get("OTP", "0")) != 0:
                flow = "OTP"
            else:
                flow = "Browser"

            self.storage.add(
                expire_time=Time.ISOtoDateTime(expires),
                stage="auth",
                authOTT=authOTT,
                mpinId=mpin_id,
                wid="",
                webOTT=0,
                authToken=token
            )

        log.debug("New M-Pin Authentication token / {0}. Flow: {1}".format(wid_flow, flow))

        # Always send 200 to PIN Pad even if the user is not authenticated
        reason = "OK"
        log.debug("%s %s" % (request_info, return_data))
        self.set_status(200, reason=reason)
        self.content_type = 'application/json'
        self.write(return_data)
        self.finish()
        return


# PRIVATE HANDLERS
class ManageGetStackInfoHandler(PrivateBaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        # Get signed API settings

        path = "apiSettings"
        expires = Time.syncedISO(seconds=SIGNATURE_EXPIRES_OFFSET_SECONDS)
        M = "{0}{1}{2}" .format(path, Keys.app_id, expires)
        signature_hex = signMessage(M, Keys.app_key)

        param_values = {
            'app_id': Keys.app_id,
            'expires': expires,
            'signature': signature_hex,
        }

        url = "{0}/{1}".format(Keys.api_url.rstrip("/"), path)
        urlParams = url_concat(url, param_values)

        client = tornado.httpclient.AsyncHTTPClient()
        response = yield tornado.gen.Task(client.fetch, urlParams, method="GET")

        status = 200

        if (response.error):
            log.error("API Request Error URL: {0}: {1}: {2}".format(url, response.error, response.body))
            status = 500
            self.set_status(status)
            self.finish()
            return

        resp_data = None
        try:
            resp_data = json.loads(response.body)
        except ValueError:
            log.error("Cannot decode JSON response from API {0}: {1}".format(url, response.body))
            status = 500
            self.set_status(status)
            self.finish()
            return

        expires = Time.syncedISO(hours=1)
        M = "{0}{1}" .format(Keys.app_id, expires)
        signature = signMessage(M, Keys.app_key)

        manage_auth_params = {
            "signature": signature,
            "expires": expires,
            "app_id": Keys.app_id
        }

        result = {
            "managementConsoleURL": resp_data.get("managementConsoleURL", ""),
            "license_info": resp_data.get("license_info", {}),
            "manage_auth": manage_auth_params
        }

        self.write(result)
        self.finish()


class UserHandler(PrivateBaseHandler):
    def post(self, mpinId):
        log.debug("Request for activationg mpinid: {0}".format(mpinId))

        try:
            data = json.loads(self.request.body)
            activateKey = data["activateKey"]
        except:
            log.error("Invalid JSON request: {0}".format(self.request.body))
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return

        I = self.storage.find(stage="register", mpinId=mpinId)
        if not I:
            log.debug("MpinID {0} not found.".format(mpinId))
            self.set_status(401, "M-Pin ID not found.")
            self.finish()
            return

        I.update(active=activateKey)
        self.set_status(200)
        self.finish()


class AuthenticateHandler(PrivateBaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        OTP = ""

        try:
            data = json.loads(self.request.body)
            authOTT = data["authOTT"]
        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return
        except KeyError:
            log.error("Invalid JSON data structure")
            log.debug(data)
            self.set_status(400, reason="BAD REQUEST. INVALID DATA")
            self.finish()
            return

        I = self.storage.find(stage="auth", authOTT=authOTT)

        if not I:
            log.error("Invalid or expired authOTT: {0}".format(authOTT))
            status = 408
            message = "Expired authentication request"
            userId = ""
            mpinId = ""
        else:
            authToken = I.authToken
            mpinId = authToken["mpin_id"].encode("hex")
            identity = json.loads(authToken["mpin_id"])
            userId = identity["userID"]

            if authToken.get("OTP", "0") != "0":
                OTP = authToken["OTP"]

            log.debug("authToken: {0}".format(authToken))

            if I.status:
                # Mobile authentication, status already set
                status = I.status
                message = I.message

                # get logout data
                logoutURL = data.get("logoutURL") or options.LogoutURL
                logoutData = data.get("logoutData")
                # If logoutURL is set, the mobile app will make a request to that URL
                # If logoutData is set, the request method will be POST otherwise it will be GET

                # If option waitForLoginResult is set, browserReady flag will be set on /loginResult request
                # from the RPA
                browserReady = (not options.waitForLoginResult)

                I.update(logoutData=logoutData, logoutURL=logoutURL, browserReady=browserReady)

                if not options.waitForLoginResult:
                    I.delete()
            else:
                (fail, status, reason) = verifyToken(authToken)

                aI = self.storage.find(stage="attempts", mpinId=mpinId)
                log.debug("aI: {0}".format(aI))
                attemptsCount = aI and aI.attemptsCount or 0
                log.debug("attemptsCount: {0}".format(attemptsCount))
                if attemptsCount >= options.maxInvalidLoginAttempts:
                    fail = 1

                if fail == 0:
                    # Authentication successful
                    message = "Authentication successful"
                    if aI:
                        aI.delete()
                else:
                    attemptsCount += 1
                    if aI:
                        aI.update(attemptsCount=attemptsCount)
                    else:
                        self.storage.add(stage="attempts", mpinId=mpinId, attemptsCount=attemptsCount)

                    if attemptsCount >= options.maxInvalidLoginAttempts:
                        status = 410

                    log.debug("Wrong PIN for user {0}.".format(userId))
                    message = "Wrong PIN."

                if not options.waitForLoginResult:
                    I.delete()

        returnData = {
            "userId": userId,
            "mpinId": mpinId,
            "status": status,
            "message": message
        }

        if OTP:
            returnData["OTP"] = OTP

        self.set_status(status, message)
        self.write(returnData)
        self.finish()


class LoginResultHandler(PrivateBaseHandler):

    def post(self):
        if not options.waitForLoginResult:
            self.set_status(404)
            self.finish()
            return

        try:
            data = json.loads(self.request.body)
            authOTT = data["authOTT"]
            status = data["status"]
        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return
        except KeyError:
            log.error("Invalid JSON data structure")
            log.debug(data)
            self.set_status(400, reason="BAD REQUEST. INVALID DATA")
            self.finish()
            return

        I = self.storage.find(stage="auth", authOTT=authOTT)

        if not I:
            log.error("Invalid or expired authOTT")
            self.set_status(408, reason="Invalid or expired authOTT")
            self.finish()
            return

        if int(status) != 200:
            I.update(status=status, message=data.get("message", I.message), browserReady=True)
        else:
            # Get the logout data
            # Logout data can be set on the previous /authenticate request as well.
            logoutURL = data.get("logoutURL") or I.logoutURL or options.LogoutURL
            logoutData = data.get("logoutData") or I.logoutData
            # If logoutURL is set, the mobile app will make a request to that URL
            # If logoutData is set, the request method will be POST otherwise it will be GET

            I.update(logoutData=logoutData, logoutURL=logoutURL, browserReady=True)

        I.delete()


class DynamicOptionsHandler(PrivateBaseHandler):
    @tornado.web.asynchronous
    def post(self):
        if options.dynamicOptionsURL:
            process_dynamic_options(
                DYNAMIC_OPTION_MAPPING,
                DYNAMIC_OPTION_HANDLERS,
                application=self.application)
            self.set_status(200, 'OK')
        else:
            self.set_status(403, 'Dynamic options are disabled')
        self.finish()

    def get(self):
        if options.dynamicOptionsURL:
            self.set_status(200, 'OK')
            self.write(generate_dynamic_options(DYNAMIC_OPTION_MAPPING))
        else:
            self.set_status(403, 'Dynamic options are disabled')


class MobileConfigHandler(BaseHandler):
    def get(self):
        if not options.mobileConfig:
            self.set_status(403, 'No config is available')
        elif not options.mobileUseNative:
            self.set_status(404, 'Native client is disabled')
        else:
            self.set_status(200, 'OK')
            self.write(json.dumps(options.mobileConfig))


class RPSCodeStatusHandler(BaseHandler):
    @tornado.web.asynchronous
    @tornado.gen.engine
    def post(self):
        try:
            data = json.loads(self.request.body)
            data['status']
        except ValueError:
            log.error("Cannot decode body as JSON.")
            log.debug(self.request.body)
            self.set_status(400, reason="BAD REQUEST. INVALID JSON")
            self.finish()
            return
        except KeyError:
            log.error("Invalid JSON data structure")
            log.debug(data)
            self.set_status(400, reason="BAD REQUEST. INVALID DATA")
            self.finish()
            return

        mobileFlow = MobileFlow(self.application, self.storage)
        params = mobileFlow.update_app_status(data)

        self.set_status(200, 'OK')
        self.write(params)
        self.finish()


# MAIN
class Application(tornado.web.Application):
    def __init__(self):
        rpsPrefix = options.rpsPrefix.strip("/")
        handlers = [
            (r"/user/([0-9A-Fa-f]+)", UserHandler),  # POST
            (r"/{0}/user(/?[0-9A-Fa-f]*)".format(rpsPrefix), RPSUserHandler),  # PUT
            (r"/{0}/signature/([0-9A-Fa-f]+)".format(rpsPrefix), RPSSignatureHandler),  # GET
            (r"/{0}/timePermit/([0-9A-Fa-f]+)".format(rpsPrefix), RPSTimePermitHandler),  # GET
            (r"/{0}/setupDone/([0-9A-Fa-f]+)".format(rpsPrefix), RPSSetupDoneHandler),  # POST
            (r"/{0}/access".format(rpsPrefix), RPSAccessHanler),  # POST
            (r"/{0}/getAccessNumber".format(rpsPrefix), RPSGetAccessNumberHandler),  # POST
            (r"/{0}/getQrUrl".format(rpsPrefix), RPSGetQrUrlHandler),  # POST
            (r"/{0}/codeStatus".format(rpsPrefix), RPSCodeStatusHandler),  # POST
            (r"/{0}/clientSettings".format(rpsPrefix), ClientSettingsHandler),
            (r"/{0}/authenticate".format(rpsPrefix), RPSAuthenticateHandler),  # POST, for mobile login
            # Authentication
            (r"/{0}/pass1".format(rpsPrefix), Pass1Handler),
            (r"/{0}/pass2".format(rpsPrefix), Pass2Handler),

            (r"/authenticate", AuthenticateHandler),  # POST

            (r"/manage/getStackInfo", ManageGetStackInfoHandler),  # GET

            (r"/loginResult", LoginResultHandler),  # POST

            (r"/status", StatusHandler),
            (r"/service", ServiceHandler),  # GET
            (r"/dynamicOptions", DynamicOptionsHandler),  # POST, GET
            (r"/{0}/mobileConfig".format(rpsPrefix), MobileConfigHandler),  # GET
            (r"/(.*)", DefaultHandler),
        ]
        settings = {}
        super(Application, self).__init__(handlers, **settings)

        Seed.getSeed(options.EntropySources)  # Get seed value for random number generator
        self.server_secret = secrets.ServerSecret(
            Seed.seedValue,
            Keys.app_id,
            Keys.app_key)

        log.debug("Using storage: {0}".format(options.storage))
        storage_cls = get_storage_cls()
        self.storage = storage_cls(
            tornado.ioloop.IOLoop.instance(),
            "stage,mpinId",
            "stage,authOTT",
            "stage,wid",
            "stage,webOTT",
            "time_permit_id,time_permit_date"
        )


def main():
    options.parse_command_line()

    if os.path.exists(options.configFile):
        try:
            options.parse_config_file(options.configFile)
            options.parse_command_line()
        except Exception, E:
            print("Invalid config file {0}".format(options.configFile))
            print(E)
            sys.exit(1)

    # Set Log level
    log.setLevel(getLogLevel(options.logLevel))

    detectProxy()

    # Load the credentials from file
    log.info("Loading credentials")
    try:
        credentialsFile = options.credentialsFile
        Keys.loadFromFile(credentialsFile)
    except Exception as E:
        log.error("Error opening the credentials file: {0}".format(credentialsFile))
        log.error(E)
        sys.exit(1)

    # TMP fix for 'ValueError: I/O operation on closed epoll fd'
    # Fixed in Tornado 4.2
    tornado.ioloop.IOLoop.instance()

    # Sync time to CertiVox time server
    if options.syncTime:
        Time.getTime(wait=True)

    Keys.getAPISettings(wait=True)

    log.info("Server starting on {0}:{1}...".format(options.address, options.port))

    http_server = Application()
    http_server.listen(options.port, options.address, xheaders=True)
    main_loop = tornado.ioloop.IOLoop.instance()
    http_server.io_loop = main_loop

    if options.autoReload:
        log.debug("Starting autoreloader")

        tornado.autoreload.watch(CONFIG_FILE)
        tornado.autoreload.start(main_loop)

    process_dynamic_options(
        DYNAMIC_OPTION_MAPPING,
        DYNAMIC_OPTION_HANDLERS,
        application=http_server,
        initial=True)

    log.info("Server started. Listening on {0}:{1}".format(options.address, options.port))
    main_loop.start()


class ServiceDaemon(Daemon):
    def run(self):
        main()


if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1].lower() in ("start", "stop"):
        action = sys.argv.pop(1)
        logFile = os.path.join(BASE_DIR, "rps.log")
        pidFile = os.path.join(BASE_DIR, "rps.pid")

        daemon = ServiceDaemon(pidfile=pidFile, stdout=logFile, stderr=logFile)
        if action == "start":
            log.info("Starting as daemon. Log file: {0}".format(logFile))
            daemon.start()
        elif action == "stop":
            log.info("Stopping daemon...")
            daemon.stop()
            sys.exit()
    else:
        try:
            main()
        except Exception as e:
            log.error(str(e))
            sys.exit(1)
