import textwrap
from pathlib import Path

from app.agent.runtime import AgentRuntimeManager
import app.agent.middleware.subagents as subagent_module


def _write_current_persona(defaults_root: Path) -> None:
    """写入最小可用的人格激活配置。"""
    defaults_root.mkdir(parents=True, exist_ok=True)
    (defaults_root / "CURRENT_PERSONA.md").write_text(
        textwrap.dedent(
            """\
            ---
            version: 3
            active_persona: default
            extra_context_files: []
            deprecated_phrases: []
            ---
            # CURRENT_PERSONA
            """
        ),
        encoding="utf-8",
    )
    persona_dir = defaults_root / "personas" / "default"
    persona_dir.mkdir(parents=True, exist_ok=True)
    (persona_dir / "PERSONA.md").write_text(
        textwrap.dedent(
            """\
            ---
            version: 1
            persona_id: default
            label: 默认
            description: 默认人格
            aliases: []
            ---
            # PERSONA

            测试人格。
            """
        ),
        encoding="utf-8",
    )


def _write_subagent(
    root: Path,
    subagent_id: str,
    *,
    version: int = 1,
    description: str = "测试子代理",
    body: str = "测试子代理提示。",
) -> Path:
    """写入一个子代理定义文件。"""
    subagent_dir = root / "subagents" / subagent_id
    subagent_dir.mkdir(parents=True, exist_ok=True)
    path = subagent_dir / "SUBAGENT.md"
    path.write_text(
        textwrap.dedent(
            f"""\
            ---
            version: {version}
            subagent_id: {subagent_id}
            label: 测试
            description: {description}
            include_tags:
              - media
              - web
            exclude_tags:
              - write
              - message
            ---
            # SUBAGENT

            {body}
            """
        ),
        encoding="utf-8",
    )
    return path


def test_runtime_syncs_and_parses_subagent_definitions(tmp_path):
    """运行时应同步并解析 defaults/subagents 下的子代理定义。"""
    defaults_root = tmp_path / "defaults"
    _write_current_persona(defaults_root)
    _write_subagent(
        defaults_root,
        "custom-reader",
        description="Custom reader subagent.",
        body="Only inspect custom media signals.",
    )

    manager = AgentRuntimeManager(
        agent_root_dir=tmp_path / "agent",
        bundled_defaults_dir=defaults_root,
    )
    runtime_config = manager.load_runtime_config()

    copied_path = (
        tmp_path
        / "agent"
        / "runtime"
        / "subagents"
        / "custom-reader"
        / "SUBAGENT.md"
    )
    subagent = runtime_config.available_subagents[0]
    assert copied_path.exists()
    assert subagent.subagent_id == "custom-reader"
    assert subagent.description == "Custom reader subagent."
    assert subagent.include_tags == ["media", "web"]
    assert subagent.exclude_tags == ["write", "message"]
    assert "Only inspect custom media signals." in subagent.text


def test_runtime_updates_bundled_subagent_when_version_increases(tmp_path):
    """内置子代理版本升高时应覆盖用户目录里的旧版副本。"""
    defaults_root = tmp_path / "defaults"
    _write_current_persona(defaults_root)
    _write_subagent(
        defaults_root,
        "custom-reader",
        version=1,
        body="version one",
    )

    manager = AgentRuntimeManager(
        agent_root_dir=tmp_path / "agent",
        bundled_defaults_dir=defaults_root,
    )
    manager.ensure_layout()

    _write_subagent(
        defaults_root,
        "custom-reader",
        version=2,
        body="version two",
    )
    manager.invalidate_cache()
    runtime_config = manager.load_runtime_config()

    subagent = runtime_config.available_subagents[0]
    assert subagent.version == 2
    assert "version two" in subagent.text


def test_middleware_profiles_are_loaded_from_runtime_config(monkeypatch, tmp_path):
    """子代理中间件应从运行时 YAML 定义生成 profile。"""
    defaults_root = tmp_path / "defaults"
    _write_current_persona(defaults_root)
    _write_subagent(
        defaults_root,
        "custom-reader",
        description="Runtime custom reader.",
        body="Runtime-only prompt.",
    )
    manager = AgentRuntimeManager(
        agent_root_dir=tmp_path / "agent",
        bundled_defaults_dir=defaults_root,
    )

    monkeypatch.setattr(subagent_module, "agent_runtime_manager", manager)
    subagent_module._builtin_subagent_profiles.cache_clear()
    subagent_module.builtin_subagent_names.cache_clear()

    profiles = subagent_module._builtin_subagent_profiles()

    assert [profile.name for profile in profiles] == ["custom-reader"]
    assert profiles[0].description == "Runtime custom reader."
    assert profiles[0].include_tags == frozenset({"media", "web"})
    assert "Runtime-only prompt." in profiles[0].prompt
