"""Cluster C4 — agent briefing/onboarding fixes (findings #3, #5, #9).

These assert on the COMPOSED system prompt (``compose_prompt``), which is
the text actually mounted into agent containers at ``/app/system-prompt.md``
via ``--system-prompt-file``. The three behaviors fixed here:

- #3: Main PM must read the upstream PO/HoM handoff BEFORE its own research,
  so it does not duplicate the Board's analysis.
- #5: Main PM's Products-vs-Projects mental model — a Product fans out to
  per-cell Projects which may be the SAME repo (monorepo subtrees) or
  DIFFERENT repos (multi-repo); the Main PM coordinates across them and
  must not assume one repo.
- #9: Developers know their exact workspace path convention, stay inside
  their own cell workspace, and obtain secrets via the task description —
  never ``env``/``printenv`` (bash-guard denies it).
"""

from __future__ import annotations

from roboco.agents.factories._base import compose_prompt
from roboco.models import AgentRole, Team


def _composed_prompt_for(role: AgentRole, team: Team | None = None) -> str:
    return compose_prompt(role, team, agent_slug="test-agent")


# --------------------------------------------------------------------------
# #3 — Main PM consumes the upstream handoff before researching/planning
# --------------------------------------------------------------------------


def test_main_pm_prompt_requires_reading_upstream_handoff_first() -> None:
    """Main PM is told to read the PO/HoM handoff BEFORE its own research."""
    prompt = _composed_prompt_for(AgentRole.MAIN_PM)
    assert "Read the upstream handoff BEFORE you research or plan" in prompt
    # Names both upstream sources explicitly.
    assert "Product Owner" in prompt
    assert "Head of Marketing" in prompt


def test_main_pm_prompt_forbids_re_researching_already_handed_work() -> None:
    """The duplicated-research failure mode is called out as an anti-pattern."""
    prompt = _composed_prompt_for(AgentRole.MAIN_PM)
    assert "Re-researching the codebase from scratch" in prompt
    # The handoff lives in the task journal as decision/reflect entries.
    assert "decision" in prompt and "reflect" in prompt


# --------------------------------------------------------------------------
# #5 — Products-vs-Projects mental model (mono- vs multi-repo)
# --------------------------------------------------------------------------


def test_main_pm_prompt_explains_product_fans_out_to_per_cell_projects() -> None:
    """Main PM prompt distinguishes Product (strategic) from per-cell Projects."""
    prompt = _composed_prompt_for(AgentRole.MAIN_PM)
    assert "Products vs Projects" in prompt
    assert "fans out to one Project per cell" in prompt


def test_main_pm_prompt_covers_both_monorepo_and_multirepo() -> None:
    """Both fan-out shapes are described; neither is assumed by default."""
    prompt = _composed_prompt_for(AgentRole.MAIN_PM)
    assert "Monorepo" in prompt
    assert "Multi-repo" in prompt
    # Must not let the agent call a monorepo subtree "a separate repo".
    assert "not" in prompt and "a separate repo" in prompt


def test_main_pm_prompt_names_prompter_monorepo_case() -> None:
    """The concrete Prompter case (all cells = one repo) is stated."""
    prompt = _composed_prompt_for(AgentRole.MAIN_PM)
    assert "github.com/rennf93/roboco" in prompt


# --------------------------------------------------------------------------
# #9 — Developer workspace path convention + secret handling
# --------------------------------------------------------------------------


def test_developer_prompt_states_exact_workspace_path_convention() -> None:
    """Developer prompt gives the exact /data/workspaces/<slug>/<team>/<slug> path."""
    prompt = _composed_prompt_for(AgentRole.DEVELOPER, Team.BACKEND)
    assert "/data/workspaces/<project-slug>/<team>/<agent-slug>/" in prompt
    # Steered to stay inside its own cell workspace.
    assert "Stay inside your own cell workspace" in prompt


def test_developer_prompt_forbids_probing_filesystem_for_workspace() -> None:
    """Developer is told not to probe / guess the workspace path."""
    prompt = _composed_prompt_for(AgentRole.DEVELOPER, Team.BACKEND)
    assert "Do NOT probe for it." in prompt
    assert "ls /" in prompt and "find /" in prompt


def test_developer_prompt_gives_sanctioned_secret_path_not_env() -> None:
    """Secrets come via the task description; env/printenv is denied."""
    prompt = _composed_prompt_for(AgentRole.DEVELOPER, Team.BACKEND)
    # env/printenv called out as denied + bash-guard blocked.
    assert "printenv" in prompt
    assert "bash-guard" in prompt
    # Sanctioned path: value provided in the task description.
    assert "in the task description" in prompt
    # Escalation route when the value is genuinely missing.
    assert "i_am_blocked" in prompt


# --------------------------------------------------------------------------
# Main PM delegation description = brief (goal + constraints), not a solution
# --------------------------------------------------------------------------


def test_main_pm_prompt_delegation_description_is_a_brief() -> None:
    """The delegate description must be a goal+constraints brief, not a spec."""
    prompt = _composed_prompt_for(AgentRole.MAIN_PM)
    assert "The description is a **brief**, not a spec." in prompt
    assert "Do NOT prescribe the cell's solution" in prompt


def test_main_pm_prompt_forbids_dictating_the_cells_design() -> None:
    """The design-task failure mode (PM dictating the UX layout) is called out."""
    prompt = _composed_prompt_for(AgentRole.MAIN_PM)
    assert "Design the UX and propose the layout" in prompt
    assert "give them the problem, not your mockup" in prompt
