from datacloud.dev_utils.logging.logger import get_basic_logger
from datacloud.launcher.update_cm.lib.cm_task import cm_task


logger = get_basic_logger(__name__)


ROBOT = 'robot_dc'
CRON_1H = '0 * * * *'
CRON_2H = '* */2 * * *'
CRON_4H = '* */4 * * *'

DAY = 60 * 60 * 24


@cm_task(robot=ROBOT, cron=CRON_2H)
def grep_spy_watch_logs_extended(status_db, args):
    from datacloud.launcher.lib.grep import datacloud_grep
    status_db.detect_ready(args.program, datacloud_grep.date_to_spy_watch_logs_extended, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, datacloud_grep.grep_all_spy_watch_logs_extended)


@cm_task(robot=ROBOT)
def update_crypta_join_tables(status_db, args):
    from datacloud.launcher.lib import update_user_yuids
    status_db.detect_ready(args.program, update_user_yuids.if_new_crypta_db, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, update_user_yuids.update_crypta_v2_join_tables)


@cm_task(robot=ROBOT, cron=CRON_2H, depends_on=[update_crypta_join_tables])
def check_crypta_stability(status_db, args):
    from datacloud.launcher.lib.routines import crypta_stability_routine
    status_db.run_task(args.program, crypta_stability_routine.check_crypta_stability)


@cm_task(robot=ROBOT, cron=CRON_2H)
def take_crypta_snapshot(status_db, args):
    from datacloud.launcher.lib.routines import snapshot_routine
    status_db.detect_ready(args.program, snapshot_routine.detect_ready, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, snapshot_routine.take_crypta_snapshot)


# cluster features
@cm_task(robot=ROBOT, cron=CRON_2H)
def cluster_hostname_extract(status_db, args):
    from datacloud.launcher.lib.routines.cluster_routine import detect_ready_hostname_extract, hostname_extract
    status_db.detect_ready(args.program, detect_ready_hostname_extract, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, hostname_extract)


@cm_task(robot=ROBOT, depends_on=[take_crypta_snapshot, cluster_hostname_extract])
def cluster_features_2(status_db, args):
    from datacloud.launcher.lib.routines.cluster_routine import build_user_vectors_2, detect_ready_build_user_vectors
    status_db.detect_ready(args.program, detect_ready_build_user_vectors, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, build_user_vectors_2)


@cm_task(robot=ROBOT, depends_on=[cluster_features_2])
def cluster_features_3(status_db, args):
    from datacloud.launcher.lib.routines.cluster_routine import build_user_vectors_3
    status_db.run_task(args.program, build_user_vectors_3)


@cm_task(robot=ROBOT, depends_on=[cluster_features_3])
def cluster_features_4(status_db, args):
    from datacloud.launcher.lib.routines.cluster_routine import build_user_vectors_4
    status_db.run_task(args.program, build_user_vectors_4)


@cm_task(robot=ROBOT, depends_on=[cluster_features_4], cron=CRON_2H, timeout=3*DAY)
def cluster_features_5(status_db, args):
    from datacloud.launcher.lib.routines.cluster_routine import build_user_vectors_5
    status_db.run_task(args.program, build_user_vectors_5)
# end cluster features


# dssm
@cm_task(robot=ROBOT, depends_on=[take_crypta_snapshot])
def dssm_175(status_db, args):
    from datacloud.launcher.lib.routines import dssm_routine
    status_db.detect_ready(args.program, dssm_routine.detect_ready_dssm_175, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, dssm_routine.run_dssm_175)


@cm_task(robot=ROBOT, depends_on=[dssm_175], timeout=3*DAY, cron=CRON_1H)
def dssm_175_combine(status_db, args):
    from datacloud.launcher.lib.routines import dssm_routine
    status_db.detect_ready(args.program, dssm_routine.detect_ready_dssm_175_combine, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, dssm_routine.run_dssm_175_combine)
# end dssm


@cm_task(robot=ROBOT, cron=CRON_1H, timeout=DAY)
def apply_models(status_db, args):
    from datacloud.launcher.lib.routines import api_models_routine
    status_db.detect_ready(args.program, api_models_routine.detect_ready,
                           args.date_hour_min, force=args.force)
    status_db.run_task(args.program, api_models_routine.run_apply_model)


@cm_task(robot=ROBOT, cron=CRON_1H, timeout=DAY, depends_on=[apply_models])
def export_audience(status_db, args):
    from datacloud.launcher.lib.routines import audience_routine
    status_db.detect_ready(args.program, audience_routine.detect_ready,
                           args.date_hour_min, force=args.force)
    status_db.run_task(args.program, audience_routine.run)


# score batch monitoring
# @cm_task(robot=ROBOT, depends_on=[apply_models], cron=CRON_2H)
# def detect_ready_tables_for_batch_monitoring(status_db, args):
    # from datacloud.launcher.lib.routines import datacloud_psi_solomon
    # status_db.detect_ready('detect_score_monitoring_by_batch', datacloud_psi_solomon.detect_ready_score_tables, args.date_hour_min, force=args.force)


# @cm_task(robot=ROBOT, depends_on=[detect_ready_tables_for_batch_monitoring],
#          cron=CRON_2H, timeout=DAY)
# def calculate_auc_hit_by_batches(status_db, args):
#     from datacloud.launcher.lib.routines import monitoring_by_batches
#     status_db.run_task('detect_score_monitoring_by_batch', monitoring_by_batches.run_batch_monitoring)
# end score batch monitoring


# psi
# @cm_task(robot=ROBOT, depends_on=[apply_models], cron=CRON_2H, timeout=DAY)
# def calculate_psi_score(status_db, args):
#     from datacloud.launcher.lib.routines import datacloud_psi_solomon
#     status_db.detect_ready(args.program, datacloud_psi_solomon.detect_ready_score_tables, args.date_hour_min, force=args.force)
#     status_db.run_task(args.program, datacloud_psi_solomon.run_calculate_psi_for_score_table)


# @cm_task(robot=ROBOT, depends_on=[apply_models], cron=CRON_2H, timeout=DAY)
# def calculate_psi_feature(status_db, args):
#     from datacloud.launcher.lib.routines import datacloud_psi_solomon
#     status_db.detect_ready(args.program, datacloud_psi_solomon.detect_ready_feature_tables, args.date_hour_min, force=args.force)
#     status_db.run_task(args.program, datacloud_psi_solomon.run_calculate_psi_for_feature_table)
# end psi


# @cm_task(robot=ROBOT,
#          depends_on=[calculate_auc_hit_by_batches, calculate_psi_score, calculate_psi_feature])
# def check_models_stability(status_db, args):
#     from datacloud.launcher.lib.routines.score_transfer_routine import assert_stability
#     status_db.run_task(args.program, assert_stability)


# @cm_task(robot=ROBOT, depends_on=[check_models_stability])
# def transfer_score(status_db, args):
#     from datacloud.launcher.lib.routines import score_transfer_routine
#     status_db.run_task(args.program, score_transfer_routine.transfer_score)


# @cm_task(robot=ROBOT, depends_on=[transfer_score], cron=CRON_2H, timeout=DAY)
# def mini_batch_monitoring(status_db, args):
#     from datacloud.launcher.lib.routines import monitoring_by_batches
#     status_db.run_task(args.program, monitoring_by_batches.run_mini_batch_monitoring)


# # Start backup
# @cm_task(robot=ROBOT)
# def backup(status_db, args):
#     from datacloud.launcher.lib.routines.backup_routine import run_backup, detect_backup_ready
#     status_db.detect_ready(args.program, detect_backup_ready, args.date_hour_min, force=args.force)
#     status_db.run_task(args.program, run_backup)


# @cm_task(robot=ROBOT, depends_on=[backup])
# def backup_compress(status_db, args):
#     from datacloud.launcher.lib.routines.backup_routine import run_backup_compress
#     status_db.run_task(args.program, run_backup_compress)


# @cm_task(robot=ROBOT, depends_on=[backup_compress], cron=CRON_2H, timeout=DAY)
# def backup_transfer(status_db, args):
#     from datacloud.launcher.lib.routines.backup_routine import run_backup_transfer
#     status_db.run_task(args.program, run_backup_transfer)


# @cm_task(robot=ROBOT, cron=CRON_4H, timeout=DAY)
# def backup_score_api(status_db, args):
#     from datacloud.launcher.lib.routines.backup_score_api_routine import detect_ready_backup_ydb, run_backup_ydb
#     status_db.detect_ready(args.program, detect_ready_backup_ydb, args.date_hour_min, force=args.force)
#     status_db.run_task(args.program, run_backup_ydb)
# End backup


# Start geo logs
@cm_task(robot=ROBOT)
def build_geo_logs(status_db, args):
    from datacloud.launcher.lib.routines.geo_logs import build_geo_logs
    from datacloud.launcher.lib.routines.geo_logs import detect_ready_geo_logs
    status_db.detect_ready(args.program, detect_ready_geo_logs, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, build_geo_logs)


@cm_task(robot=ROBOT, depends_on=[build_geo_logs])
def build_geo_aggregates(status_db, args):
    from datacloud.launcher.lib.routines.geo_logs import build_geo_aggregates
    status_db.run_task(args.program, build_geo_aggregates)


# @cm_task(robot=ROBOT, depends_on=[build_geo_aggregates])
# def transfer_log_to_ydb(status_db, args):
#     from datacloud.launcher.lib.routines.transfer_geo_to_ydb import transfer_geo_to_ydb
#     status_db.run_task(args.program, partial(transfer_geo_to_ydb, is_transfer_crypta=False))


# @cm_task(robot=ROBOT, depends_on=[transfer_log_to_ydb])
# def transfer_crypta_to_ydb(status_db, args):
#     from datacloud.launcher.lib.routines.transfer_geo_to_ydb import transfer_geo_to_ydb
#     status_db.run_task(args.program, partial(transfer_geo_to_ydb, is_transfer_crypta=True))


# @cm_task(robot=ROBOT, depends_on=[transfer_crypta_to_ydb], cron=CRON_4H, timeout=DAY)
# def run_rotate_geo_tables(status_db, args):
#     from datacloud.launcher.lib.routines.transfer_geo_to_ydb import rotate_geo_tables
#     status_db.run_task(args.program, rotate_geo_tables)
# End geo logs


# @cm_task(robot=ROBOT)
# def save_crypta_matches(status_db, args):
#     from datacloud.launcher.lib.routines import save_crypta_matches
#     status_db.detect_ready(args.program, save_crypta_matches.detect_ready, args.date_hour_min, force=args.force)
#     status_db.run_task(args.program, save_crypta_matches.save_matches)


# @cm_task(robot=ROBOT, depends_on=[save_crypta_matches], cron=CRON_4H, timeout=DAY)
# def blend_crypta_matches(status_db, args):
#     from datacloud.launcher.lib.routines import blend_crypta_matches
#     status_db.run_task(args.program, blend_crypta_matches.run_blend_crypta_matches)


@cm_task(robot=ROBOT, cron=CRON_2H, depends_on=[grep_spy_watch_logs_extended])
def contact_actions_grep(status_db, args):
    from datacloud.launcher.lib.routines.contact_actions_routine import detect_ready_contact_actions_grep, run_contact_actions_grep
    status_db.detect_ready(args.program, detect_ready_contact_actions_grep, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, run_contact_actions_grep)


@cm_task(robot=ROBOT, cron=CRON_2H,
         depends_on=[contact_actions_grep, take_crypta_snapshot])
def build_contact_actions_features(status_db, args):
    from datacloud.launcher.lib.routines.contact_actions_routine import detect_ready_contact_actions_features, run_contact_actions_features
    status_db.detect_ready(args.program, detect_ready_contact_actions_features, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, run_contact_actions_features)


@cm_task(robot=ROBOT, cron=CRON_2H, depends_on=[grep_spy_watch_logs_extended])
def time_hist_grep(status_db, args):
    from datacloud.launcher.lib.routines.time_hist_routine import detect_ready_time_hist_grep, run_time_hist_grep
    status_db.detect_ready(args.program, detect_ready_time_hist_grep, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, run_time_hist_grep)


@cm_task(robot=ROBOT, cron=CRON_2H, depends_on=[time_hist_grep, take_crypta_snapshot])
def build_time_hist_features(status_db, args):
    from datacloud.launcher.lib.routines.time_hist_routine import detect_ready_time_hist_features, run_time_hist_features
    status_db.detect_ready(args.program, detect_ready_time_hist_features, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, run_time_hist_features)


@cm_task(robot=ROBOT, cron=CRON_2H, depends_on=[build_time_hist_features])
def build_phone_range_features(status_db, args):
    from datacloud.launcher.lib.routines.phone_range_routine import detect_ready_phone_range_features, run_phone_range_features
    status_db.detect_ready(args.program, detect_ready_phone_range_features, args.date_hour_min, force=args.force)
    status_db.run_task(args.program, run_phone_range_features)
