"""
回归测试：验证 generation_tasks.py 中兜底关联 edit plan 在 enqueue 之前执行。

根因（PR #1481 后续修复）：兜底关联逻辑原来在 safe_enqueue_generation_task 之后执行，
导致 worker 在 enqueue 后立即读取 task 时，source_edit_plan_id 仍为空（竞态条件）。
"""

import ast
import textwrap


def _get_function_source(filepath, func_name):
    """提取函数源码"""
    with open(filepath) as f:
        source = f.read()
    tree = ast.parse(source)
    for node in ast.walk(tree):
        if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)) and node.name == func_name:
            lines = source.splitlines()
            start = node.lineno - 1
            end = node.end_lineno
            return textwrap.dedent("\n".join(lines[start:end]))
    return None


def _find_try_block_source(func_source):
    """在函数源码中找到包含 safe_enqueue_generation_task 的 try 块"""
    tree = ast.parse(textwrap.dedent(func_source))
    for node in ast.walk(tree):
        if isinstance(node, ast.Try):
            # 检查 try 块中是否包含 safe_enqueue_generation_task
            block_lines = func_source.splitlines()
            block_text = "\n".join(block_lines[node.lineno - 1 : node.end_lineno])
            if "safe_enqueue_generation_task" in block_text:
                return block_text
    return None


def test_fallback_before_enqueue():
    """验证兜底关联 edit plan 的代码在 safe_enqueue_generation_task 调用之前"""
    filepath = "apps/api/app/api/routes/generation_tasks.py"
    func_source = _get_function_source(filepath, "create_generation_task")
    assert func_source is not None, "create_generation_task function not found"

    try_block = _find_try_block_source(func_source)
    assert try_block is not None, "try block with safe_enqueue_generation_task not found"

    # 定位关键标记在 try 块中的行号
    lines = try_block.splitlines()

    fallback_line = None
    enqueue_line = None
    writeback_line = None

    for i, line in enumerate(lines):
        if "not task.source_edit_plan_id and request.template_id" in line and fallback_line is None:
            fallback_line = i
        if "safe_enqueue_generation_task(" in line and enqueue_line is None:
            enqueue_line = i
        if "_writeback_edit_plan_config(" in line and "def " not in line and writeback_line is None:
            writeback_line = i

    assert fallback_line is not None, "兜底关联逻辑 not found in try block"
    assert enqueue_line is not None, "safe_enqueue_generation_task call not found in try block"
    assert writeback_line is not None, "_writeback_edit_plan_config call not found in try block"

    # 核心断言：兜底关联和回写都在 enqueue 之前
    assert fallback_line < enqueue_line, f"兜底关联（行{fallback_line}）应在 enqueue（行{enqueue_line}）之前"
    assert writeback_line < enqueue_line, f"回写 config（行{writeback_line}）应在 enqueue（行{enqueue_line}）之前"


def test_fallback_sets_source_edit_plan_id():
    """验证兜底关联逻辑会设置 task.source_edit_plan_id"""
    filepath = "apps/api/app/api/routes/generation_tasks.py"
    func_source = _get_function_source(filepath, "create_generation_task")
    assert func_source is not None

    try_block = _find_try_block_source(func_source)
    assert try_block is not None

    # 验证兜底逻辑包含赋值语句
    assert "task.source_edit_plan_id = _plan_model.id" in try_block, "兜底关联逻辑应设置 task.source_edit_plan_id"
    assert "generation_task_repository.update(task)" in try_block, "兜底关联后应持久化 task 到 DB"


def test_writeback_uses_effective_plan_id():
    """验证回写 config 使用的是 effective_plan_id（包含兜底结果），而非仅 request.source_edit_plan_id"""
    filepath = "apps/api/app/api/routes/generation_tasks.py"
    func_source = _get_function_source(filepath, "create_generation_task")
    assert func_source is not None

    try_block = _find_try_block_source(func_source)
    assert try_block is not None

    # 验证使用了 _effective_plan_id 或 task.source_edit_plan_id，而非仅 request.source_edit_plan_id
    # 修复前用的是 request.source_edit_plan_id，修复后应该用 task.source_edit_plan_id
    uses_effective = "_effective_plan_id" in try_block or "task.source_edit_plan_id" in try_block
    assert uses_effective, "回写 config 应使用包含兜底结果的有效 plan_id"
