#! -*- coding: utf-8 -*-
import logging
import os

import tornado.ioloop
import tornado.web
from raven.contrib.tornado import AsyncSentryClient, SentryMixin

from constants import LISTEN_PORT, OAUTH_TOKEN
from staff import Staff

logger = logging.getLogger(__name__)


class BaseStaffHandler(tornado.web.RequestHandler):
    staff = Staff(oauth_token=OAUTH_TOKEN)

    @classmethod
    def jsonify(cls, func):
        def wrapper(self):
            self.set_header("Content-Type", "application/json; charset=UTF-8")
            func(self)
        return wrapper

    def write_wrapper(self, data):
        if isinstance(data, dict):
            staff_api_status_code = data.get("status_code", 200)
            if staff_api_status_code != 200:
                self.send_error(status_code=staff_api_status_code)
                return
        self.write(data)


class GroupUsersHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(self.staff.get_group_users(group_url=self.get_argument('url', '')))


class SuggestUser(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        many_arg = self.get_argument('many', '').lower()
        self.write_wrapper(
            self.staff.get_user_info(
                login=self.get_argument('login', ''),
                many=many_arg == 'true' or many_arg == '1',
            ),
        )


class UserGroupsHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(self.staff.get_user_groups(login=self.get_argument('login', '')))


class UserLocationHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(self.staff.get_user_location(login=self.get_argument('login', '')))


class ChiefUsersHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(
            self.staff.get_chief_users(
                login=self.get_argument('login', ''),
                with_nested=self.get_argument('with_nested', '') in ['true', '1'],
            )
        )


class HrUsersHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(
            self.staff.get_hr_partner_users(
                login=self.get_argument('login', ''),
            )
        )


class UserRolesHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(self.staff.get_user_roles(login=self.get_argument('login', '')))


class GroupsHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(self.staff.get_groups(
            page=self.get_argument('page', ''),
            limit=self.get_argument('limit', ''),
        ))


class OfficesHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(self.staff.get_offices(
            page=self.get_argument('page', ''),
            limit=self.get_argument('limit', ''),
        ))


class AutoGroupsHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(self.staff.get_auto_groups_membership(
            login=self.get_argument('login', '')
        ))


class HasDepartmentRoleHandler(BaseStaffHandler):
    @BaseStaffHandler.jsonify
    def get(self):
        self.write_wrapper(self.staff.has_department_role(
            login=self.get_argument('login', ''),
            role=self.get_argument('role', ''),
        ))


class PingHandler(BaseStaffHandler):
    def get(self):
        self.write_wrapper('pong')


def make_app():
    return tornado.web.Application([
        (r"/ping", PingHandler),
        (r"/groupusers", GroupUsersHandler),
        (r"/suggestuser", SuggestUser),
        (r"/usergroups", UserGroupsHandler),
        (r"/userlocation", UserLocationHandler),
        (r"/chiefusers", ChiefUsersHandler),
        (r"/hrusers", HrUsersHandler),
        (r"/userroles", UserRolesHandler),
        (r"/groups", GroupsHandler),
        (r"/offices", OfficesHandler),
        (r"/autogroups", AutoGroupsHandler),
        (r"/hasdepartmentrole", HasDepartmentRoleHandler),
    ])


if __name__ == "__main__":
    app = make_app()

    sentry_dsn = os.environ.get('SENTRY_DSN', None)
    if sentry_dsn:
        logger.debug("Using sentry exception logging (dsn: {})".format(sentry_dsn))
        app.sentry_client = AsyncSentryClient(sentry_dsn)
        BaseStaffHandler.__bases__ = (SentryMixin, ) + BaseStaffHandler.__bases__

    app.listen(LISTEN_PORT)
    print("Starting service on :{}".format(LISTEN_PORT))
    tornado.ioloop.IOLoop.current().start()
