#!/usr/bin/env 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
import uuid
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,
)

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}/accessnumber".format(baseURL)
            params["getAccessNumberURL"] = "{0}/getAccessNumber".format(baseURL)

        if options.mobileUseNative:
            params["getQrUrl"] = "{0}/getQrUrl".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):
        # Generate request for MPinWIDServer for WID
        wId = uuid.uuid4().hex

        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 = uuid.uuid4().hex

        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)

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

        self.write(params)
        self.finish()


class RPSAccessNumberHandler(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

        I = self.storage.find(stage="auth", webOTT=webOTT)
        if not I:
            log.debug("Cannot find webOTT: {0}".format(webOTT))

            self.set_status(404)
            self.finish()
            return

        authOTT = I.authOTT
        if authOTT and (str(I.status) == "200"):
            self.write({"authOTT": authOTT})
            self.finish()
        else:
            if not authOTT:
                log.debug("authOTT not set for webOTT: {0}".format(webOTT))
            else:
                log.debug("Auth status for webOTT: {0}: {1}".format(webOTT, I.status))
            self.set_status(401)
            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))


# 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}/accessnumber".format(rpsPrefix), RPSAccessNumberHandler),  # POST
            (r"/{0}/getAccessNumber".format(rpsPrefix), RPSGetAccessNumberHandler),  # POST
            (r"/{0}/getQrUrl".format(rpsPrefix), RPSGetQrUrlHandler),  # 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)
