# -*- coding: utf-8 -*-
from datacloud.dev_utils.solomon.solomon_utils import post_sensors_to_solomon, str2ts
from datacloud.dev_utils.logging.logger import get_basic_logger
from datacloud.stability.crypta_stability.constants import (
    HASH_PHONE_TO_CID_Q, HASH_EMAIL_TO_CID_Q, YUID_TO_CID_Q,
    DEFAULT_TAG, TMP_FOLDER, UNIQUE_CIDS_Q,
    SOLOMON_PROJECT, SOLOMON_CLUSTER, MEAN_SERVICE, SHARE_SERVICE
)
from datacloud.stability.crypta_stability.helpers import (
    id_value_counter, accumulate_counter, join_cids_with_cids,
    reduce_unique_cids, get_creation_date
)
from datacloud.stability.crypta_stability.tables import id_values_log

logger = get_basic_logger(__name__)

id_types2table = {
    'phone_id_value': HASH_PHONE_TO_CID_Q,
    'email_id_value': HASH_EMAIL_TO_CID_Q,
    'yuid': YUID_TO_CID_Q
}


def upload_id_value_stable_to_solomon(service, crypta_date, type, value):
    sensors = [{
        'labels': {
            'type': type,
        },
        'ts': str2ts(crypta_date),
        'value': value
    }]
    post_sensors_to_solomon(SOLOMON_PROJECT, SOLOMON_CLUSTER, service, sensors)


def upload_id_value_dicts_to_solomon(crypta_date, type2mean, type2share):
    for id_type, value in type2mean.iteritems():
        upload_id_value_stable_to_solomon(MEAN_SERVICE, crypta_date, id_type, value)

    for id_type, value in type2share.iteritems():
        upload_id_value_stable_to_solomon(SHARE_SERVICE, crypta_date, id_type, value)


def check_id_value_stability(yt_client, tag=DEFAULT_TAG):
    reduce_unique_cids(
        yt_client=yt_client,
        input_paths=id_types2table.values(),
        result=UNIQUE_CIDS_Q,
        tag=tag
    )
    all_unique_cids = yt_client.row_count(UNIQUE_CIDS_Q)

    type2mean = dict()
    type2share = dict()
    with yt_client.Transaction(), yt_client.TempTable(TMP_FOLDER) as temp_table:

        for id_type, table in id_types2table.iteritems():
            yt_client.run_map_reduce(
                None,
                join_cids_with_cids,
                [
                    yt_client.TablePath(table, columns=['cid']),
                    yt_client.TablePath(UNIQUE_CIDS_Q, columns=['cid']),
                ],
                temp_table,
                reduce_by='cid',
                spec={'title': '[{}] get cids share {}'.format(tag, id_type)}
            )
            type2share[id_type] = float(yt_client.row_count(temp_table)) / all_unique_cids
            logger.info('Share of {} is {}'.format(id_type, type2share[id_type]))

            yt_client.run_map_reduce(
                None,
                id_value_counter,
                yt_client.TablePath(table, columns=['cid']),
                temp_table,
                reduce_by='cid',
                spec={'title': '[{}] count id_values'.format(tag)},
            )
            cids_count = yt_client.row_count(temp_table)

            yt_client.run_map(
                accumulate_counter,
                temp_table,
                temp_table,
                spec={'title': '[{}] count id_values / accumulate'.format(tag)}
            )

            acc_count = accumulate_counter(yt_client.read_table(temp_table, raw=False)).next()
            type2mean[id_type] = float(acc_count['count']) / cids_count

            logger.info('Mean of {} is {}'.format(id_type, type2mean[id_type]))

    crypta_date = get_creation_date(yt_client, HASH_EMAIL_TO_CID_Q)

    log_table = id_values_log.CryptaStabilityIdValueTable()
    log_table.add_record_by_dicts(
        crypta_date=crypta_date,
        type2mean=type2mean,
        type2share=type2share
    )
    upload_id_value_dicts_to_solomon(
        crypta_date=crypta_date,
        type2mean=type2mean,
        type2share=type2share
    )
