"""Tests for colony console display helpers."""

from io import StringIO

from rich.console import Console

from fliiq.runtime.colony import console as colony_console
from fliiq.runtime.colony.models import (
    AgentRole,
    ColonyState,
    GovernanceDecision,
    IntelBrief,
    Proposal,
    ProposalStatus,
    ProposalType,
    QAMetrics,
    RiskLevel,
    Vote,
    VotePosition,
)


def _capture() -> tuple[Console, StringIO]:
    """Create a console that writes to a string buffer."""
    buf = StringIO()
    con = Console(
        file=buf, force_terminal=True, width=80, highlight=False,
    )
    return con, buf


def _patch_console(monkeypatch, con):
    """Swap the module-level console for our captured one."""
    monkeypatch.setattr(colony_console, "console", con)


class TestExperimentHeader:
    def test_shows_experiment_id(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        state = ColonyState(
            experiment_id=1,
            branch_name="colony/experiment-001",
            cycle_count=5,
        )
        colony_console.print_experiment_header(state, 0.5, 2.0)
        output = buf.getvalue()
        assert "Experiment 001" in output
        assert "colony/experiment-001" in output


class TestAgentLifecycle:
    def test_agent_start(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        colony_console.print_agent_start(
            "intelligence", "Scan AI landscape",
        )
        output = buf.getvalue()
        assert "Intelligence" in output
        assert "Scan AI landscape" in output

    def test_agent_done(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        colony_console.print_agent_done("qa", 7)
        output = buf.getvalue()
        assert "7 iterations" in output

    def test_agent_error(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        colony_console.print_agent_error("governance", "API timeout")
        output = buf.getvalue()
        assert "API timeout" in output


class TestArtifactAnnouncements:
    def test_new_brief(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        brief = IntelBrief(
            id="INTEL-TEST01",
            title="Claude 5 released",
            source_type="blog",
            relevance="direct",
            summary="Major model update.",
        )
        colony_console.print_new_brief(brief)
        output = buf.getvalue()
        assert "INTEL-TEST01" in output
        assert "Claude 5" in output

    def test_new_proposal(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        p = Proposal(
            id="PROP-TEST01",
            title="Add caching",
            type=ProposalType.ARCHITECTURE_CHANGE,
            risk=RiskLevel.MEDIUM,
            proposer=AgentRole.RESEARCH,
        )
        colony_console.print_new_proposal(p)
        output = buf.getvalue()
        assert "PROP-TEST01" in output
        assert "Add caching" in output

    def test_new_vote(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        v = Vote(
            proposal_id="PROP-TEST01",
            voter=AgentRole.QA,
            position=VotePosition.SUPPORT,
            reasoning="Tests pass.",
        )
        colony_console.print_new_vote(v)
        output = buf.getvalue()
        assert "SUPPORT" in output
        assert "Tests pass" in output

    def test_governance_decision(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        d = GovernanceDecision(
            proposal_id="PROP-TEST01",
            outcome=ProposalStatus.APPROVED,
            reasoning="Evidence strong.",
            commit_sha="abc123def",
        )
        colony_console.print_governance_decision(d)
        output = buf.getvalue()
        assert "APPROVED" in output
        assert "abc123def" in output


class TestDashboard:
    def test_proposal_board(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        p = Proposal(
            id="PROP-BOARD1",
            title="Test proposal",
            type=ProposalType.BUG_FIX,
            risk=RiskLevel.LOW,
            proposer=AgentRole.QA,
            status=ProposalStatus.APPROVED,
        )
        colony_console.print_proposal_board([p], {"PROP-BOARD1": 2})
        output = buf.getvalue()
        assert "PROP-BOARD1" in output
        assert "APPROVED" in output

    def test_empty_board(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        colony_console.print_proposal_board([], {})
        assert buf.getvalue() == ""

    def test_metrics_summary(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        m = QAMetrics(
            test_count=520, pass_count=518,
            fail_count=2, lint_issues=1,
        )
        colony_console.print_metrics_summary(m)
        output = buf.getvalue()
        assert "520" in output
        assert "518" in output


class TestLifecycle:
    def test_shutdown_summary(self, monkeypatch):
        con, buf = _capture()
        _patch_console(monkeypatch, con)
        state = ColonyState(
            experiment_id=1,
            branch_name="colony/experiment-001",
            cycle_count=42,
            proposals_total=5,
            proposals_approved=3,
            proposals_rejected=1,
        )
        colony_console.print_shutdown_summary(state)
        output = buf.getvalue()
        assert "Complete" in output
        assert "42" in output
