# -*- coding: utf-8 -*-
import json
import uuid
import yt.wrapper as yt
import requests
import time
import os
import logging

from saas.library.python.token_store import PersistentTokenStore

YT_TABLE_PATH = '//home/saas/ssm/quotas_data'

author = {'passportUid': '1120000000006245', 'staffLogin': 'saku'}

API_HOSTNAME = "http://abcd.saas.yandex.net"
API_HOSTNAME_T = "http://saas-abcd-test.in.yandex-team.ru"

API_ACCOUNTS = "/quotaManagement/v1/providers/{}/accounts"

PROVIDER_ID = "1ae09b4f-091b-481f-af89-10f01b9adf14"
PROVIDER_ID_T = "b44a0e54-0a5e-424a-bd61-b632952753da"
D_API = "https://d-api.yandex-team.ru/api/v1/services/"
D_API_T = "https://d.test.yandex-team.ru/api/v1/services/"

request_headers = {'Authorization': 'OAuth %s' % os.getenv('D_TOKEN')}


def yt_get_table(path=YT_TABLE_PATH, cluster='hahn'):
    yt_client = yt.YtClient(proxy=cluster, token=PersistentTokenStore.get_token_from_store_env_or_file('yt'))
    return list(yt_client.read_table(path, format=yt.JsonFormat(encoding="utf-8")))


def read_quotas():
    return yt_get_table()


def get_folder_id(abc_id, env_type="prod"):
    if env_type == "prod":
        API_URL = D_API
    else:
        API_URL = D_API_T
    request_url = API_URL + str(abc_id) + '/folders'
    response = requests.get(request_url, headers=request_headers)
    if response.ok:
        for folder in response.json()['items']:
            if folder['folderType'] == 'COMMON_DEFAULT_FOR_SERVICE':
                return folder['id']
    print(abc_id, response.text)


def convert_quotas(quotas_data):
    for quota in quotas_data:
        for resource in quota:
            if resource in ['HDD', 'SSD', 'RAM']:
                for location in quota[resource]:
                    quota[resource][location] = quota[resource][location] / 1024 / 1024 / 1024
    return quotas_data


def prepare_account_request(abc_id, abc_name, env_type="prod"):
    account_data = {}
    folder_id = get_folder_id(abc_id, env_type)
    if not folder_id:
        logging.error(f"Folder ID for service {abc_name}:{abc_id} was not found. Skipping service")
        return
    account_data['key'] = abc_name
    account_data['displayName'] = abc_name
    account_data['abcServiceId'] = abc_id
    account_data['folderId'] = folder_id
    account_data['author'] = author
    account_data['operationId'] = str(uuid.uuid4())
    account_data['freeTier'] = False
    return account_data


def get_accounts(env_type="prod"):
    accounts_data = []
    if env_type == "prod":
        api_accounts = API_ACCOUNTS.format(PROVIDER_ID)
        api_hostname = API_HOSTNAME
    else:
        api_accounts = API_ACCOUNTS.format(PROVIDER_ID_T)
        api_hostname = API_HOSTNAME_T
    response = requests.post(api_hostname + api_accounts + '/_getPage', json={'limit': 100})
    print(response)
    if response.ok:
        for account in response.json()['accounts']:
            a = {
                'accountId': account['accountId'],
            }
            for quota in quotas:
                if account['key'] == quota['quota_abc_name']:
                    a['abcServiceId'] = quota['quota_abc_id']
                    a['folderId'] = get_folder_id(quota['quota_abc_id'], env_type)
                    break
            accounts_data.append(a)
    return accounts_data


def prepare_provisions(env_type="prod"):
    accounts = get_accounts(env_type)
    quotas = read_quotas()
    quotas_data = convert_quotas(quotas)
    account_provisions_data = {}
    for quota in quotas_data:
        provisions_data = []
        for resource in quota:
            resource_key = resource.lower()
            if resource_key in ['hdd', 'ssd', 'ram']:
                unit_key = "gibibytes"
            elif resource_key == 'cpu':
                unit_key = "millicores"
            else:
                continue
            for location in quota[resource]:
                resource_amount = int(quota[resource][location])
                resource_dict = {
                    'resourceKey': {
                        'resourceTypeKey': resource_key,
                        'segmentation': [
                            {
                                'segmentationKey': 'cluster',
                                'segmentKey': location.lower()
                            }
                        ]
                    },
                    'providedAmount': resource_amount,
                    'providedAmountUnitKey': unit_key
                }
                provisions_data.append(resource_dict)
        for account in accounts:
            if account.get('abcServiceId') == quota['quota_abc_id']:
                account_provisions = {
                    'folderId': account['folderId'],
                    'abcServiceId': account['abcServiceId'],
                    'updatedProvisions': provisions_data,
                    'author': author,
                    'operationId': str(uuid.uuid4())
                }
                account_provisions_data[account['accountId']] = account_provisions
                break
    return account_provisions_data


def create_accounts(env_type="prod"):
    if env_type == "prod":
        api_path = API_ACCOUNTS.format(PROVIDER_ID)
        api_hostname = API_HOSTNAME
    else:
        api_path = API_ACCOUNTS.format(PROVIDER_ID_T)
        api_hostname = API_HOSTNAME_T
    for quota in read_quotas():
        abc_id = quota['quota_abc_id']
        abc_name = quota['quota_abc_name']
        account_data = prepare_account_request(abc_id, abc_name, env_type)
        if not account_data:
            continue
        response = requests.post(api_hostname + api_path, data=json.dumps(account_data))
        print(response.url)
        print(response.text)


def send_provisions_update(env_type="prod"):
    if env_type == "prod":
        api_path = API_ACCOUNTS.format(PROVIDER_ID)
        api_hostname = API_HOSTNAME
    else:
        api_path = API_ACCOUNTS.format(PROVIDER_ID_T)
        api_hostname = API_HOSTNAME_T
    provisions_data = prepare_provisions(env_type)
    for account in provisions_data:
        response = requests.post(api_hostname + api_path + '/' + account + '/_provide', json=provisions_data[account])
        print(response.url)
        print(response.json())
