from patch.include import *
from tqdm import tqdm


@app_context(commit=True)
def gantt_fix():
    """
    Для тестирования патча: ( cd /opt/eva-app; python3 -m patch. )
    Добавляет :default в лоджиктайпы для согласования, исправляет запись
    """
    print('Запуск патча gantt_fix')

    # Патч 202306301130_gantt_baseline_refactor_clone.py не везде применен, либо был с ошибкой
    for baseline in models.CmfGanttBaseline.list(filter=['is_operate', '=', True],
                                                      include_deleted=True, fields=['cmf_deleted']):
        while True:
            gantt_task_list = models.CmfGanttTask.list(parent=baseline, slice=[0, 1000])
            if not gantt_task_list:
                break
            for gantt_task in gantt_task_list:
                gantt_task.parent = None
                gantt_task.save(only_data=True)
                print(f'Fix op_gantt_task.parent = None {baseline} -> {gantt_task}')
            commit_with_event()
        if not baseline.cmf_deleted:
            print(f'Delete operate baseline {baseline}')
            baseline.delete()
            commit_with_event()

    # Скорость: 65000 задач за 0m40.048s ~10мин на 1млн задач
    # UPD slist: 6000 в сек, ~3мин на 1млн задач
    i = 0
    no_gantt_task = []
    bad_gantt_task = []
    while True:
        task_list = models.CmfTask.slist(slice=[i, i+10000], order_by=['cmf_created_at'], TECHCOM_nocache=True,
                                         fields=['op_gantt_task.task_id', 'parent', 'logic_prefix', 'parent_task'])
        print(f'Обработано {i} задач')
        i += 10000
        if not task_list:
            break
        for t in task_list:
            if not t.op_gantt_task:
                # print(f'Bad task! No op_gantt_task t={t}({t.cmf_created_at.load()})')
                print(f'Bad task! No op_gantt_task t={t}')
                no_gantt_task.append(t.id)
                continue
            if t.op_gantt_task.task_id != t.id:
                print(f'Bad task! Чужой op_gantt_task t={t}')
                # print(f'Bad task! Чужой op_gantt_task t={t}({t.cmf_created_at.load()}) '
                #       f'gantt={t.op_gantt_task.task.load()}({t.op_gantt_task.task.cmf_created_at.load()})')
                bad_gantt_task.append(t.id)

    if no_gantt_task:
        print('Иправляем no_gantt_task')
        task_list = models.CmfTask.list(filter=['id', 'IN', no_gantt_task],
                                         fields=['op_gantt_task.task_id',
                                                 'parent', 'logic_prefix',
                                                 'parent_task', 'cmf_created_at', 'parent.main_gantt_project'])
        for t in task_list:
            print(f'Bad task! No op_gantt_task t={t}({t.cmf_created_at}) op_gantt_task={t.op_gantt_task}')
            # !!! Остался кейс, когда мы не создаем op_gantt_task - когда у проекта не выставлен main_gantt_project
            # TODO1: убрать защиту в _calc_gantt_task и загенерить им гантт-таски
            if t.parent and t.parent.value.class_name == 'CmfProject' and not t.parent.main_gantt_project:
                print('У проекта не выставлен гант-проект, пропускаем.')
                continue
            t._calc_gantt_task()
            t.save(only_data=True, emit=False, notify=False)

    if bad_gantt_task:
        print('Иправляем bad_gantt_task')
        task_list = models.CmfTask.list(filter=['id', 'IN', bad_gantt_task],
                                        fields=['op_gantt_task.task_id',
                                                'op_gantt_task.task.cmf_created_at',
                                                'parent', 'logic_prefix',
                                                'parent_task', 'cmf_created_at'])
        for t in task_list:
            print(f'Bad task! Чужой op_gantt_task t={t}({t.cmf_created_at}) '
                  f'gantt={t.op_gantt_task.task_id}({t.op_gantt_task.task.cmf_created_at})')
            t._clone_op_gantt_task(t)
            # t.op_gantt_task = None
            # t.save()

if __name__ == "__main__":
    gantt_fix()
