import logging
import requests
import urllib

from load.projects.lunaparkapi.settings import base


class NoTvmTicket(Exception):
    pass


class NoStaffInfo(Exception):
    pass


class NoUidInfo(Exception):
    pass


class StaffInfo:
    def __init__(self, login=None, is_dismissed=False, is_robot=False, uid=None):
        self.login = login
        self.is_dismissed = is_dismissed
        self.is_robot = is_robot
        self.uid = uid


class User:
    def __init__(self, login=None, uid=None, user_ticket=None):
        self.staff_info = StaffInfo(login=login, uid=uid)

        self.user_ticket = user_ticket
        if self.user_ticket:
            try:
                uid = self.__ticket_to_uid()
                self.__get_staff_info(uid=uid)
            except NoStaffInfo:
                logging.error('Failed to get staff info')

    @staticmethod
    def __get_tvm_ticket(src=base['TVM_ID'], dest=base['STAFF_TVM_ID']):
        logging.debug('Get tvm ticket for dest %s...', dest)
        try:
            response = requests.get(
                '{tvmtool_url}/tvm/tickets?src={src}&dsts={dest}'.format(
                    tvmtool_url=base['DEPLOY_TVM_TOOL_URL'], src=src, dest=dest
                ),
                headers={'Authorization': base['TVMTOOL_LOCAL_AUTHTOKEN']}
            )
            service_ticket = response.json()['staff_api_prod']['ticket']
            return service_ticket
        except Exception:
            logging.error('Failed to get tvm ticket', exc_info=True)
            raise NoTvmTicket

    def __staff_req(self, params):
        logging.debug('Get staff info for params %s...', params)
        url = 'https://{}/v3/person?{}'.format(base['STAFF_URL'], urllib.urlencode(params))
        headers = {
            'Host': 'staff-api.yandex-team.ru',
            'X-Ya-Service-Ticket': self.__get_tvm_ticket()
        }

        try:
            resp = requests.get(url, verify=False, timeout=10, headers=headers)
            return resp.json()['result'][0]
        except Exception:
            logging.error('Failed to get staff info', exc_info=True)
            raise NoStaffInfo

    def __get_staff_info(self, uid=None, login=None):
        logging.debug('Get staff info for uid %s, login %s...', uid, login)
        params = {}
        if uid:
            params['uid'] = uid
        if login:
            params['login'] = login

        try:
            staff_info = self.__staff_req(params)
            logging.debug('Staff info: %s', staff_info)
            self.staff_info.login = staff_info['login']
            self.staff_info.uid = staff_info['uid']
            self.staff_info.is_robot = staff_info['official']['is_robot']
            self.staff_info.is_dismissed = staff_info['official']['is_dismissed']
        except Exception:
            logging.error('Exception while parsing staff', exc_info=True)
            raise NoStaffInfo

    def __ticket_to_uid(self):
        logging.debug('Get uid from ticket...')
        url = '{tvmtool_url}/tvm/checkusr'.format(tvmtool_url=base['DEPLOY_TVM_TOOL_URL'])
        try:
            response = requests.get(url, headers={
                'Authorization': base['TVMTOOL_LOCAL_AUTHTOKEN'],
                'X-Ya-User-Ticket': self.user_ticket
            })
            logging.debug('Response %s %s', response.status_code, response.text)
            uid = response.json()['default_uid']
            logging.debug('Uid %s', uid)
            return uid
        except Exception:
            logging.error('Failed to get tvm ticket', exc_info=True)
            raise NoUidInfo
