# -*- coding: utf-8 -*-
import os
from datacloud.score_api.storage.crypta.generic import CryptaStorage

# TODO: Move ecoders storage/crypta/encoders
# TODO: Нужно ли encode_cookie ??
from datacloud.dev_utils.id_value.encoders import encode_id_value, encode_phone, encode_email, encode_yuid, encode_cookie

from datacloud.score_api.storage.ydb.ydb_tables.score_tables.crypta_table import CryptaTable
from datacloud.score_api.storage.ydb.ydb_tables.config_tables.partner_scores_table import PartnerScoresTable


__all__ = [
    'YdbCryptaStorage'
]


class YdbCryptaStorage(CryptaStorage):
    def __init__(self, driver, database, partner_score_table):
        """
        Params:
            version(int, default 2): Version of crypta to use. Possible values: 1; 2.
        """
        super(YdbCryptaStorage, self).__init__()
        self._driver = driver
        self._database = database
        self._partner_scores_table = PartnerScoresTable(driver, database, partner_score_table)

    def _get_crypta_table(self, partner_id, partner_score_name):
        internal_score_name = self._partner_scores_table.get_one(partner_id, partner_score_name).internal_score_name
        score_path = self._score_path_table.get_one(internal_score_name).score_path
        crypta_path = os.path.join(self._scores_root, score_path, 'crypta')
        crypta_table = CryptaTable(self._driver, self._database, crypta_path)
        return crypta_table

    @staticmethod
    def _index_lookup(index, partner_id, partner_score_name, id_values):
        rows = index.lookup_rows({'hashed_id_value': id_value} for id_value in id_values)
        return set(cid for row in rows for cid in row['hashed_cids'])

    @staticmethod
    def _convert_to_id_values(info, cookies):
        encoders = {
            'id_value': encode_id_value,
            'phone': encode_phone,
            'email': encode_email,
            'yuid': encode_yuid,
        }
        for record in info:
            for id_type in record:
                if id_type in encoders:
                    id_value = encoders[id_type](record[id_type])
                    if id_value:
                        yield id_value
        for cookie in cookies:
            if 'cookie_vendor' in cookie and 'cookie' in cookie:
                yield encode_cookie(vendor=cookie['cookie_vendor'], value=cookie['cookie'])

    def lookup_cids(self, partner_score_name, person_ids, cookies):
        """
        Returns hashed to uint64 cids for given contacts
        `person_ids` is list of dict like [{'id_value': '...', 'phone': '...', 'email': '...'}]
        `cookies` is list of dict like [{'cookie_vendor': '...', 'cookie': '...'}]
        """
        all_id_values = list(self._convert_to_id_values(person_ids, cookies))
        if not all_id_values:
            return set()
        return self._index_lookup(self._crypta_tables.id_value_to_cid, all_id_values)
