from patch.include import *
from tqdm import tqdm
import tempfile

def read_ids_from_file(file_path, batch_size):
    ids = []
    with open(file_path, 'r') as file:
        for line in file:
            ids.append(line.strip())
            if len(ids) == batch_size:
                yield ids
                ids = []
    if ids:
        yield ids

@app_context(commit=True)
def fix_acl():
    """
    Для тестирования патча: ( cd /opt/eva-app; python3 -m patch.202406251321_fix_acl )
    Здесь можно работать с моделями через models.CmfTask и т.д.
    Для прогрессбара используйте:
    for task in tqdm(models.CmfTask.list()):
        ...
    """
    print('Запуск патча fix_acl')
    batch_size = 100
    cnt = models.CmfTask.count(filter=['parent_task', '!=', None])
    with tempfile.TemporaryDirectory() as tmp_dir_name:
        file_path = f'{tmp_dir_name}/ids.list'
        with open(file_path, 'w+') as f:
            for start in range(0, cnt, batch_size):
                for obj in models.CmfTask.slist(filter=['parent_task', '!=', None], 
                                                fields=['--'], slice=[start, start + batch_size]):
                    f.write(obj.id + '\n')
        
        for batch_ids in read_ids_from_file(file_path, batch_size):
            # Формирование фильтра по текущему батчу идентификаторов
            filter_condition = ['id', 'IN', batch_ids]

            # Получение задач по текущему батчу идентификаторов
            tasks = models.CmfTask.list(filter=filter_condition, fields=['parent', 'parent_task', 'perm_parent.logic_prefix'])
            for t in tasks:
                if t.parent_task.id != t.perm_parent.id:
                    print(t.parent_task, t.perm_parent)
                    t.parent_task.is_changed = True
                    t._calc_perm_parent()
                    t.save(only_data=True)
                    t.dp.commit()
    cnt = models.CmfTask.count(filter=['parent_task', '=', None])
    with tempfile.TemporaryDirectory() as tmp_dir_name:
        file_path = f'{tmp_dir_name}/ids.list'
        with open(file_path, 'w+') as f:
            for start in range(0, cnt, batch_size):
                for obj in models.CmfTask.slist(filter=['parent_task', '=', None], 
                                                fields=['--'], slice=[start, start + batch_size]):
                    f.write(obj.id + '\n')            
                    
        for batch_ids in read_ids_from_file(file_path, batch_size):
        
            # Формирование фильтра по текущему батчу идентификаторов
            filter_condition = ['id', 'IN', batch_ids]

            # Получение задач по текущему батчу идентификаторов
            tasks = models.CmfTask.list(filter=filter_condition, fields=['parent', 'parent_task', 'perm_parent.logic_prefix'])
            for t in tasks:
                if t.perm_parent and hasattr(t.perm_parent, 'logic_prefix') and t.perm_parent.logic_prefix == 'task.gantt_project':
                    print(t.parent_task, t.perm_parent)
                    t.parent_task.is_changed = True
                    t._calc_perm_parent()
                    t.save(only_data=True)
                    t.dp.commit()


if __name__ == "__main__":
    fix_acl()