import subprocess
import psycopg
import requests
import logging
import json

TOKENS = {
    'robot-dispenser': {'ver': 'ver-01dj5e0vzsw63m6mv15etzmv13', 'key': 'oauth_token'},
    'robot-tracker': {'ver': 'ver-01d54mks4epb6phqh03tkjnk3d', 'key': 'tracker_oauth'},
    'bot-prod': {'ver': 'ver-01dhtvq5cgg0qe5bjncds6f158', 'key': 'oauth_token'},
    'testing_db': {'ver': 'ver-01emr5b2rw8prhkz994j46jxmz', 'key': 'password'},
    'prod_db': {'ver': 'ver-01emr5cj2vkznrnzmz0g7ncnqv', 'key': 'password'}
}


def get_secret_value(ver, key):
    return subprocess.Popen(['ya', 'vault', 'get', 'version', ver, '-n', '-o', key],
                            stdout=subprocess.PIPE).stdout.read().decode('utf8')


def get_token(key):
    params = TOKENS[key]
    return get_secret_value(params['ver'], params['key'])


def prod_password():
    return get_token("prod_db")


def testing_password():
    return get_token("testing_db")


def robot_dispenser_token():
    return get_token("robot-dispenser")


def robot_tracker_token():
    return get_token("robot-tracker")


def common_testing_connection():
    return psycopg.connect(f"""
        host=man-65p53fqgfjg9vz9o.db.yandex.net,sas-sryxv84a8ba7m1dk.db.yandex.net,vla-998kbuokjq8nzbxt.db.yandex.net
        port=6432
        dbname=dispenser_common_testing
        user=dispenser
        password={testing_password()}
        target_session_attrs=read-write
        sslmode=verify-full
    """)


def common_prod_connection():
    return psycopg.connect(f"""
        host=man-f10sh5xrioku6izp.db.yandex.net,sas-z3btrew8mc1moza1.db.yandex.net,vla-92csqm2om2u3rww3.db.yandex.net
        port=6432
        dbname=dispenser_common_production
        user=dispenser
        password={prod_password()}
        target_session_attrs=read-write
        sslmode=verify-full
    """)


def configure_logging(filename):
    logging.basicConfig(filename=filename, filemode='w', level=logging.DEBUG,
                        format='%(asctime)s - [%(levelname)s] - %(message)s')


class Response:
    def __init__(self, body, status):
        self.body = body
        self.status = status

    def __str__(self):
        return f"{self.status} ({self.body})"


class Dispenser:

    def __init__(self, prod, cluster='', override_token=None):
        self.token = robot_dispenser_token() if override_token is None else override_token
        if prod:
            self.host = 'https://dispenser.yandex-team.ru/'
        else:
            self.host = 'https://dispenser.test.yandex-team.ru/'

        if cluster != '':
            self.host += cluster + '/'

    def prepare_headers(self, additional={}):
        return {
            "Authorization": f"OAuth {self.token}",
            **additional
        }

    def get_requests(self, **params):
        headers = self.prepare_headers()
        resp = requests.get(self.host + 'api/v1/quota-requests', headers=headers, params=params)
        res = resp.json()
        if resp.status_code != 200:
            return Response(res, resp.status_code)
        return Response(res['result'], resp.status_code)

    def set_quota_state(self, body, suppress_summon=True):
        headers = self.prepare_headers({
            "Content-Type": "application/json"
        })
        resp = requests.patch(self.host + 'api/v1/resource-preorder/quotaState', data=json.dumps(body),
                              headers=headers, params={"suppressSummon": suppress_summon})
        res = resp.json()
        return Response(res, resp.status_code)

    def set_quota_state_optional(self, body, suppress_summon=True):
        headers = self.prepare_headers({
            "Content-Type": "application/json"
        })
        resp = requests.patch(self.host + 'api/v1/resource-preorder/quotaStateOptional', data=json.dumps(body),
                              headers=headers, params={"suppressSummon": suppress_summon})
        res = resp.json()
        return Response(res, resp.status_code)

    def allocate_provider(self, request_id, provider):
        headers = self.prepare_headers()
        resp = requests.post(self.host + f'api/v1/resource-preorder/{request_id}/provider-allocation/{provider}',
                             headers=headers)
        res = resp.json()
        return Response(res, resp.status_code)

    def refresh_ticket(self, ticket_key, suppressSummon=True, summonAssignee=False):
        headers = self.prepare_headers()
        resp = requests.post(self.host + f"api/admin/requests/_refresh/{ticket_key}", headers=headers,
                             params={"suppressSummon": suppressSummon, "summonAssignee": summonAssignee})
        res = resp.json()
        return Response(res, resp.status_code)

    def admin_change_status(self, tickets, to_status, history_comment, suppressSummon=True):
        headers = self.prepare_headers({"Content-Type": "application/json"})
        resp = requests.post(self.host + f"api/admin/requests/_changeStatus/tickets", headers=headers,
                             data=json.dumps(list(tickets)),
                             params={"historyComment": history_comment, "suppressSummon": suppressSummon,
                                     "toStatus": to_status})
        res = resp.text
        return Response(res, resp.status_code)


class Tracker:

    def __init__(self, prod, override_token=None):
        self.token = robot_tracker_token() if override_token is None else override_token
        if prod:
            self.host = 'https://st-api.yandex-team.ru/'
        else:
            self.host = 'https://st-api.test.yandex-team.ru/'

    def _prepare_headers(self, additional={}):
        return {
            "Authorization": f"OAuth {self.token}",
            **additional
        }

    def post_comment(self, ticket, comment):
        headers = self._prepare_headers()
        return requests.post(f'{self.host}v2/issues/{ticket}/comments',
                             headers=headers, data=json.dumps({"text": comment}))
