"""T6 通用生成器执行器单测：`run_generator` + `build_brief_context`。

注入 mock 网关（产 IdeaListResult parsed），无真 LLM、无真 Postgres。通用执行器据
`spec.output_schema` 校验 parsed（不绑定具体类型）；只产结构化产物，**不写库**（纯预览，
不变量 #3）。asyncio_mode=auto。
"""

from __future__ import annotations

import uuid

import pytest
from fakes_orchestrator import FailingRunGateway, FakeRunGateway
from ww_agents import Idea, IdeaListResult, brainstorm_spec
from ww_core.orchestrator import build_brief_context, run_generator

PROJECT = uuid.UUID("00000000-0000-0000-0000-000000000001")
USER = uuid.UUID("00000000-0000-0000-0000-0000000000aa")

_IDEAS = IdeaListResult(
    ideas=[
        Idea(premise="废柴觉醒吞噬瞳", hook="升级要付记忆", genre_fit="玄幻"),
        Idea(premise="末世种粮农场主", hook="粮食成硬通货"),
    ]
)


# ---- run_generator：返回结构化产物，据 output_schema 校验，只读不写库 ----


async def test_run_generator_returns_structured_result() -> None:
    gateway = FakeRunGateway(_IDEAS)

    result = await run_generator(
        brainstorm_spec,
        context=build_brief_context(brief="来点逆袭流", project_context="题材：玄幻"),
        gateway=gateway,
        user_id=USER,
        project_id=PROJECT,
    )

    assert isinstance(result, IdeaListResult)
    assert len(result.ideas) == 2
    assert result.ideas[0].premise == "废柴觉醒吞噬瞳"


async def test_run_generator_passes_tier_and_schema_to_gateway() -> None:
    # 不变量 #2：只透传档位（light），不传 model；output_schema 据 spec 绑定
    gateway = FakeRunGateway(_IDEAS)

    await run_generator(
        brainstorm_spec,
        context="x",
        gateway=gateway,
        user_id=USER,
        project_id=PROJECT,
    )

    assert gateway.last_request is not None
    assert gateway.last_request.tier == "light"
    assert gateway.last_request.output_schema is IdeaListResult


async def test_run_generator_raises_on_gateway_failure() -> None:
    # 独立生成：网关失败直接上抛（端点处理），不静默吞
    gateway = FailingRunGateway(RuntimeError("boom"))

    with pytest.raises(RuntimeError, match="boom"):
        await run_generator(
            brainstorm_spec,
            context="x",
            gateway=gateway,
            user_id=USER,
            project_id=PROJECT,
        )


# ---- build_brief_context：确定性、空需求降级占位 ----


def test_build_brief_context_is_deterministic() -> None:
    a = build_brief_context(brief="逆袭", project_context="题材：玄幻")
    b = build_brief_context(brief="逆袭", project_context="题材：玄幻")
    assert a == b
    assert "题材：玄幻" in a
    assert "逆袭" in a


def test_build_brief_context_empty_brief_falls_back() -> None:
    ctx = build_brief_context(brief="   ", project_context="题材：都市")
    assert "按题材自由发散" in ctx
