from yt.wrapper import ypath_split
from datacloud.stability import score_psi_to_yt_and_solomon, feature_psi_to_yt_and_solomon
from datacloud.model_applyer.lib.features_v2 import DSSMFeature, ClusterFeature
from datacloud.dev_utils.logging.logger import get_basic_logger
from datacloud.dev_utils.yt.yt_utils import get_yt_client
from datacloud.model_applyer.tables.models_config_table import ApiModelsConfigTable
from datacloud.model_applyer.utils.helpers import (
    get_all_score_tables, get_all_blended_score_tables,
    PURE_SCORE_TYPE, BLENDED_SCORE_TYPE
)


logger = get_basic_logger(__name__)
COMMAND_SEPARATOR = '#'
SCORE_FOLDER = '//home/x-products/production/datacloud/models'
EXCEPTION_LIST = ['hcb_card_and_cash', 'rko_model_20170922']


def detect_ready_score_tables(date_time, days=None):
    def _make_task_data(table, model, score_type):
        return {'table_path': table,
                'partner_id': model['partner_id'],
                'score_name': model['score_name'],
                'score_date': ypath_split(table)[-1],
                'score_type': score_type}

    yt_client = get_yt_client()
    for model in ApiModelsConfigTable().list_active_models():
        score_tables = get_all_score_tables(
            yt_client=yt_client,
            partner_id=model['partner_id'],
            score_name=model['score_name']
        )
        for table in score_tables:
            yield table, _make_task_data(table, model, PURE_SCORE_TYPE)

        if model['additional'].get(ApiModelsConfigTable.SCORE_BLEND_ON_KEY, False):
            blended_tables = get_all_blended_score_tables(
                yt_client=yt_client,
                partner_id=model['partner_id'],
                score_name=model['score_name']
            )
            for table in blended_tables:
                yield table, _make_task_data(table, model, BLENDED_SCORE_TYPE)


def run_calculate_psi_for_score_table(task):
    yt_client = get_yt_client()
    input_table = task.data['table_path']
    logger.info('Start upload table: {}'.format(task))

    score_name = task.data['score_name']
    score_date = task.data['score_date']
    score_type = task.data['score_type']
    score_psi_to_yt_and_solomon.run_calculate_score_psi_table(
        yt_client, input_table, score_name, score_date, score_type)
    return [task.make_done()]


def detect_ready_feature_tables(date_time, days=None, days2take_dssm=25):
    yt_client = get_yt_client()

    dssm_tables = sorted(yt_client.list(DSSMFeature.get_weekly_folder(), absolute=True))
    dssm_feature_name = DSSMFeature().feature_name

    for i, table in enumerate(dssm_tables, 1):
        command = COMMAND_SEPARATOR.join((dssm_feature_name, table))
        yield command, {
            'feature_name': dssm_feature_name,
            'date_str': ypath_split(table)[-1],
            'first_table': dssm_tables[max(0, i - days2take_dssm)],
            'last_table': dssm_tables[i - 1]
        }

    for feature in (ClusterFeature, ):
        featrue_name = feature().feature_name

        for table in sorted(yt_client.list(feature.get_weekly_folder(), absolute=True)):
            command = COMMAND_SEPARATOR.join((feature().feature_name, table))
            yield command, {
                'feature_name': featrue_name,
                'date_str': ypath_split(table)[-1],
                'first_table': table,
                'last_table': table
            }


def run_calculate_psi_for_feature_table(task):
    yt_client = get_yt_client()
    logger.info('Start upload table: {}'.format(task))
    feature_psi_to_yt_and_solomon.run_calculate_feature_psi_table(
        yt_client=yt_client,
        date_str=task.data['date_str'],
        feature_name=task.data['feature_name'],
        first_table=task.data['first_table'],
        last_table=task.data['last_table']
    )
    return [task.make_done()]


if __name__ == '__main__':
    pass
