from patch.include import *
from tqdm import tqdm


@app_context(commit=True)
def patch_scaffold_project_perm():
    """
    Для тестирования патча: ( cd /opt/eva-app; python3 -m patch.202402091343_scaffold_sd_private_project_perm_scheme )
    Здесь можно работать с моделями через models.CmfTask и т.д.
    Для прогрессбара используйте:
    for task in tqdm(models.CmfTask.list()):
        ...
    """
    # патч пересоздан
    exit(0)
    from cmf.system_data import scaffold_project_perm

    system_ppp_is_changed = False
    s = models.CmfProjectPermScheme.get(code='system:default')
    if not s:
        # хак для bcrm и стендов разработки с частично примененными патчами
        s = models.CmfProjectPermScheme.get(code='old_system202403:default')
    for sr in models.CmfProjectPermSchemeRule.list(parent=s, fields=['cmf_modified_by']):
        if sr.cmf_modified_by != models.CmfPerson.system_person():
            system_ppp_is_changed = True
            print('Схема по-умолчанию изменена, не обрабатываем автоматически флаг disable_simple_perm!')

    old_delfault = models.CmfProjectPermScheme.get(code='system:default')
    if old_delfault:
        old_delfault.system = False
        old_delfault.code = 'old_system202403:default'
        old_delfault.save(only_data=True)

    from cmf.system_data import scaffold_project_perm

    with cmfutil.disable_acl(), cmfutil.disable_notify():
        print('scaffold_project_perm')
        scaffold_project_perm()


    # Получаем проекты с ACL-правами, но без ручных правил

    projects_with_acl = {}
    projects_no_acl = {}
    for project in models.CmfProject.list(filter=['perm_policy','!=','default']):
        found = False
        for model_cls in cmf.models.CmfEntity.iter_subclasses():
            if found:
                break
            if model_cls.class_name in ('CmfAccessList', 'CmfAccessRule'):
                continue
            for obj in model_cls.list(filter=[['project','=',project],['perm_acl','!=',None]], fields=['perm_acl.rules.sys_type']):
                # print(project, project.perm_policy, obj, obj.perm_acl, obj.perm_acl.rules)
                for r in obj.perm_acl.rules:
                    if r.sys_type =='auto':
                        continue
                    projects_with_acl[project.id.value] = project.perm_policy
                    found = True
                    # print(project, project.perm_policy, obj, obj.perm_acl, obj.perm_acl.rules, obj.perm_policy)
                    break
        if not found:
            projects_no_acl[project.id.value] = project.perm_policy

    print(len(projects_with_acl), models.CmfProject.count())
    print(len(projects_no_acl))


    # 	если старая схема из коробки не исправлена и у проекта она стоит
    # 		если не стоит disable_simple_perm, то
    # 			ставим ограниченную схему
    # 		иначе
    # 			ставим открытую схему
    # 		конецесли
    # 	концесли

    if not system_ppp_is_changed:
        for project in models.CmfProject.list(filter=['project_perm_scheme.code', '=', 'system:default'],
                                              fields=['disable_simple_perm']):
            # if project.disable_simple_perm:
            #     project.project_perm_scheme = models.CmfProjectPermScheme.get(code='system.open:default')
            # else:
            #     project.project_perm_scheme = models.CmfProjectPermScheme.get(code='system.team_private:default')

            project.project_perm_scheme = models.CmfProjectPermScheme.get(code='system.open:default')
            # Если у проекта стоит perm_policy и нет ручных правил - выставляем схему
            if project.id.value in projects_no_acl:
                if projects_no_acl[project.id.value] == 'full':
                    pass
                elif projects_no_acl[project.id.value] == 'readonly':
                    project.project_perm_scheme = models.CmfProjectPermScheme.get(code='system.team_limited:default')
                elif projects_no_acl[project.id.value] == 'private':
                    project.project_perm_scheme = models.CmfProjectPermScheme.get(code='system.team_private:default')
                project.perm_policy = 'default'
            project.save()


if __name__ == "__main__":
    patch_scaffold_project_perm()
