from patch.include import *

from sqlalchemy import update, select, func

import cmf.app
import cmf.data_providers.base


@app_context(commit=True)
def patch():
    """
    Обновление моделей multichoice после добавления поля cust_field_conf_id
    Этот патч обновляет файлы моделей multichoice, чтобы они содержали поле cust_field_conf_id
    Для тестирования патча: ( cd /opt/eva-app; python3 -m patch.202511211238_conf_custom_choice_update_models )
    """
    logging.info(f'Run patch {__file__}')

    dd = cmf.data_providers.base.get_dd('default')
    session = dd.Session()

    cmf_document_history_table = models.CmfDocumentHistory.dp_model.__table__
    cmf_document_table = models.CmfDocument.dp_model.__table__

    src_stmt = (
        select((cmf_document_history_table.c.id, cmf_document_table.c.project_id))
        .select_from(
            cmf_document_history_table.join(
                cmf_document_table,
                cmf_document_history_table.c.parent_id == cmf_document_table.c.id))
        .where(
            func.coalesce(cmf_document_history_table.c.project_id, 'null')
            != func.coalesce(cmf_document_table.c.project_id, 'null'))
        .order_by(cmf_document_history_table.c.cmf_created_at)
        .limit(500)
        .alias('src')
    )

    update_stmt = (
        update(cmf_document_history_table)
        .values(project_id=src_stmt.c.project_id)
        .where(cmf_document_history_table.c.id == src_stmt.c.id)
    )

    total_row_count = 0
    update_count = 0

    while True:
        result = session.execute(update_stmt)
        total_row_count += result.rowcount
        update_count += 1
        session.commit()

        if not result.rowcount:
            break

        if update_count >= 5000:
            logging.error(f'Too many updates {update_count}, {total_row_count}')
            break

    if total_row_count:
        logging.info(f'Invalidate document history cache')
        cmf.app.CMF_CACHE.invalidate_ids(models.CmfDocumentHistory.class_name, None)
    logging.info(f'Update {total_row_count} document history records')


if __name__ == "__main__":
    init_logging()
    patch()
