import pytest
from brigade.selection import (
    Selection,
    HARNESS_PRIORITY,
    KNOWN_HARNESSES,
    KNOWN_DEPTHS,
    KNOWN_INCLUDES,
    WRITER_INBOXES,
    resolve_owner,
)


def test_opencode_is_a_known_harness():
    from brigade.selection import KNOWN_HARNESSES, WRITER_INBOXES
    assert "opencode" in KNOWN_HARNESSES
    assert WRITER_INBOXES["opencode"] == ".opencode/memory-handoffs"


def test_antigravity_is_a_known_harness():
    from brigade.selection import KNOWN_HARNESSES, WRITER_INBOXES
    assert "antigravity" in KNOWN_HARNESSES
    assert WRITER_INBOXES["antigravity"] == ".antigravity/memory-handoffs"


def test_pi_is_a_known_harness():
    from brigade.selection import KNOWN_HARNESSES, WRITER_INBOXES
    assert "pi" in KNOWN_HARNESSES
    assert WRITER_INBOXES["pi"] == ".pi/memory-handoffs"


def test_cursor_is_a_known_harness():
    from brigade.selection import KNOWN_HARNESSES, WRITER_INBOXES
    assert "cursor" in KNOWN_HARNESSES
    assert WRITER_INBOXES["cursor"] == ".cursor/memory-handoffs"


def test_expanded_cli_harnesses_are_known_writers():
    from brigade.selection import KNOWN_HARNESSES, WRITER_INBOXES

    for harness in ("aider", "goose", "continue", "copilot", "qwen", "kimi", "adal", "openhands"):
        assert harness in KNOWN_HARNESSES
        assert WRITER_INBOXES[harness] == f".{harness}/memory-handoffs"


def test_writer_inboxes_cover_known_writers():
    from brigade.selection import WRITER_INBOXES
    assert WRITER_INBOXES["claude"] == ".claude/memory-handoffs"
    assert WRITER_INBOXES["codex"] == ".codex/memory-handoffs"
    assert WRITER_INBOXES["antigravity"] == ".antigravity/memory-handoffs"
    assert WRITER_INBOXES["pi"] == ".pi/memory-handoffs"
    assert WRITER_INBOXES["cursor"] == ".cursor/memory-handoffs"
    assert WRITER_INBOXES["aider"] == ".aider/memory-handoffs"
    assert WRITER_INBOXES["goose"] == ".goose/memory-handoffs"
    assert WRITER_INBOXES["continue"] == ".continue/memory-handoffs"
    assert WRITER_INBOXES["copilot"] == ".copilot/memory-handoffs"
    assert WRITER_INBOXES["qwen"] == ".qwen/memory-handoffs"
    assert WRITER_INBOXES["kimi"] == ".kimi/memory-handoffs"
    assert WRITER_INBOXES["adal"] == ".adal/memory-handoffs"
    assert WRITER_INBOXES["openhands"] == ".openhands/memory-handoffs"
    assert WRITER_INBOXES["hermes"] == ".hermes/memory-handoffs"


def test_harness_priority_order():
    assert HARNESS_PRIORITY == ["openclaw", "hermes", "claude", "codex", "this-repo"]


def test_resolve_owner_picks_highest_priority_present():
    assert resolve_owner(["claude", "openclaw"]) == "openclaw"
    assert resolve_owner(["claude", "codex"]) == "claude"
    assert resolve_owner(["codex"]) == "codex"
    assert resolve_owner(["hermes", "claude"]) == "hermes"


def test_resolve_owner_empty_selection_returns_this_repo():
    assert resolve_owner([]) == "this-repo"


def test_resolve_owner_explicit_override_wins():
    assert resolve_owner(["claude", "openclaw"], override="claude") == "claude"
    assert resolve_owner(["claude"], override="this-repo") == "this-repo"


def test_resolve_owner_rejects_override_not_in_selection():
    with pytest.raises(ValueError, match="not in selected harnesses"):
        resolve_owner(["claude"], override="openclaw")


def test_resolve_owner_accepts_this_repo_override_always():
    assert resolve_owner(["openclaw"], override="this-repo") == "this-repo"


def test_selection_dataclass_holds_fields():
    sel = Selection(
        depth="workspace",
        harnesses=["claude", "codex"],
        owner="claude",
        includes=["publisher"],
    )
    assert sel.depth == "workspace"
    assert sel.harnesses == ["claude", "codex"]
    assert sel.owner == "claude"
    assert sel.includes == ["publisher"]


def test_selection_validate_rejects_unknown_depth():
    with pytest.raises(ValueError, match="unknown depth"):
        Selection(depth="weird", harnesses=["claude"], owner="claude", includes=[]).validate()


def test_selection_validate_rejects_unknown_harness():
    with pytest.raises(ValueError, match="unknown harness"):
        Selection(depth="repo", harnesses=["claude", "weird"], owner="claude", includes=[]).validate()


def test_selection_validate_rejects_owner_not_in_harnesses():
    with pytest.raises(ValueError, match="owner.*not in selected harnesses"):
        Selection(depth="repo", harnesses=["claude"], owner="openclaw", includes=[]).validate()


def test_selection_validate_accepts_this_repo_owner_with_empty_harnesses():
    Selection(depth="repo", harnesses=[], owner="this-repo", includes=[]).validate()


def test_known_constants():
    assert set(KNOWN_HARNESSES) == {
        "claude",
        "codex",
        "opencode",
        "antigravity",
        "pi",
        "cursor",
        "aider",
        "goose",
        "continue",
        "copilot",
        "qwen",
        "kimi",
        "adal",
        "openhands",
        "openclaw",
        "hermes",
    }
    assert set(KNOWN_DEPTHS) == {"repo", "workspace"}
    assert set(KNOWN_INCLUDES) == {"publisher"}
