"""T6 脑洞生成器契约测试：spec + schema（创作工具箱通用框架首个最简生成器）。

契约测试——构造符合 schema 的 mock 响应，校验字段、tier、读写权限。
brainstorm：`{ideas:[{premise,hook,genre_fit}]}`（轻量档，reads=projects，writes=[] 纯预览）。
不联网、无 DB。
"""

from __future__ import annotations

import pytest
from pydantic import ValidationError
from ww_agents import (
    AgentSpec,
    Idea,
    IdeaListResult,
    brainstorm_spec,
)

# ---- IdeaListResult schema ----


def test_idea_list_parses_mock_response() -> None:
    # Arrange：模拟网关 instructor 校验后的结构化脑洞产出
    mock = {
        "ideas": [
            {
                "premise": "废柴觉醒可吞噬规则的瞳术",
                "hook": "每次升级都要付出一段记忆为代价",
                "genre_fit": "玄幻·热血",
            },
            {"premise": "末世里唯一能种粮的农场主", "hook": "粮食成了最硬的通货"},
        ]
    }

    # Act
    result = IdeaListResult.model_validate(mock)

    # Assert
    assert len(result.ideas) == 2
    assert result.ideas[0].premise == "废柴觉醒可吞噬规则的瞳术"
    assert result.ideas[0].hook == "每次升级都要付出一段记忆为代价"
    assert result.ideas[0].genre_fit == "玄幻·热血"
    assert result.ideas[1].genre_fit is None  # 可缺


def test_idea_list_defaults_to_empty() -> None:
    assert IdeaListResult().ideas == []


def test_idea_requires_premise_and_hook() -> None:
    with pytest.raises(ValidationError):
        Idea.model_validate({"premise": "只有前提没有钩子"})


# ---- brainstorm_spec 声明 ----


def test_brainstorm_spec_is_light_tier() -> None:
    # 不变量 #2：脑洞发散用轻量档，只声明 tier
    assert brainstorm_spec.tier == "light"
    assert brainstorm_spec.name == "brainstorm"


def test_brainstorm_spec_reads_projects_writes_nothing() -> None:
    # 纯预览：读作品设定、不写任何业务表（不变量 #3）
    assert brainstorm_spec.reads == ("projects",)
    assert brainstorm_spec.writes == ()


def test_brainstorm_spec_output_schema() -> None:
    assert brainstorm_spec.output_schema is IdeaListResult


def test_brainstorm_spec_prompt_documents_diversification() -> None:
    # 一次多条须逐条差异化——system_prompt 必须强调
    assert "差异化" in brainstorm_spec.system_prompt


def test_brainstorm_spec_is_agent_spec_and_immutable() -> None:
    assert isinstance(brainstorm_spec, AgentSpec)
    with pytest.raises(ValidationError):
        brainstorm_spec.tier = "writer"
