# encoding: utf-8
from __future__ import unicode_literals

import logging
import time

from tornado import gen, web
from ylog.context import log_context

from intranet.webauth.lib.authorizer import Authorizer
from intranet.webauth.lib.utils import request_log_context

logger = logging.getLogger(__name__)

LOGIN_HEADER = b'X-Webauth-Login'
UID_HEADER = b'X-Webauth-Uid'


class AuthRequestHandler(web.RequestHandler):
    # disables response caching
    def compute_etag(self):
        return None

    @gen.coroutine
    def get(self):
        with log_context(**request_log_context(self.request)):
            start_time = time.time()
            logger.info('Incoming request')

            auth = Authorizer.from_request(self.request)
            status, info = yield auth.get()
            if status:
                yield self.accept_request(*info)
                request_ms = round(time.time() - start_time, 4) * 1000
                logger.info('Webauth request: accept, %f ms', request_ms)
            else:
                yield self.decline_request(*info)
                request_ms = round(time.time() - start_time, 4) * 1000
                logger.info('Webauth request: decline, %f ms', request_ms)

    # this function used to return 403 error for client
    # we need to return the reasons for the denied request and blackbox_login (if it is determined)
    @gen.coroutine
    def decline_request(self, reasons, login="", uid=""):
        self.set_status(403 if login else 401)
        self.set_header(b'Content-type', 'text/plain')
        self.set_header(LOGIN_HEADER, login)
        self.set_header(UID_HEADER, uid)
        self.set_header(b'Webauth-Denial-Reasons', '; '.join(reasons))
        self.set_header(b'Connection', 'Close')
        answer_text = ''
        for reason in reasons:
            answer_text += reason + "\n"

        with log_context(login=login, reasons=reasons):
            logger.info('Denied request')
        self.finish(answer_text.encode("utf-8"))

    @gen.coroutine
    def accept_request(self, login, uid):
        self.set_status(200)
        self.set_header(b'Content-type', 'text/plain')
        self.set_header(LOGIN_HEADER, login)
        self.set_header(UID_HEADER, uid)
        self.set_header(b'Connection', 'Close')
        with log_context(login=login):
            logger.info('Accepted request')
        self.finish(b'Auth completed\n')
