"""Content assertion tests for skill/agent tool references and plugin paths.

Locks the contract that all skill and agent documentation contains the
expected job lifecycle tool references introduced in M003. Also verifies
that every skill path listed in ``plugin.json`` resolves to an existing
directory.

These are static content tests — they read files from the repo, not from
the MCP server. No ``fastmcp`` import is needed.
"""

from __future__ import annotations

import json
from pathlib import Path

import pytest

# Resolve the repository root (5 levels up from this test file)
REPO_ROOT = Path(__file__).resolve().parents[3]


def _read_skill(relative_path: str) -> str:
    """Read a file relative to the repo root and return its content."""
    path = REPO_ROOT / relative_path
    assert path.exists(), f"Expected file not found: {path}"
    return path.read_text()


class TestSkillContentAssertions:
    """Verify job lifecycle tool names appear in updated skills and agents."""

    @pytest.mark.parametrize(
        ("file_path", "expected_tool"),
        [
            ("skills/vm-ground-control/SKILL.md", "vm_job_start"),
            ("skills/vm-ground-control/SKILL.md", "vm_job_step"),
            ("skills/vm-ground-control/SKILL.md", "vm_job_pause"),
            ("skills/vm-ground-control/SKILL.md", "vm_job_complete"),
            ("skills/vm-scenario-runner/SKILL.md", "vm_fleet_status"),
            ("skills/vm-scenario-runner/SKILL.md", "vm_job_list"),
            ("skills/vm-fleet-ops/SKILL.md", "vm_job_resume"),
            ("skills/vm-fleet-ops/SKILL.md", "vm_fleet_status"),
            ("skills/vm-fleet-ops/SKILL.md", "vm_job_list"),
        ],
        ids=[
            "ground-control-vm_job_start",
            "ground-control-vm_job_step",
            "ground-control-vm_job_pause",
            "ground-control-vm_job_complete",
            "scenario-runner-vm_fleet_status",
            "scenario-runner-vm_job_list",
            "fleet-ops-vm_job_resume",
            "fleet-ops-vm_fleet_status",
            "fleet-ops-vm_job_list",
        ],
    )
    def test_skill_contains_tool_reference(self, file_path: str, expected_tool: str) -> None:
        """Each skill must reference the specified job lifecycle tool name.

        Args:
            file_path: Path to the skill SKILL.md relative to repo root.
            expected_tool: Tool name substring that must appear in the file.
        """
        content = _read_skill(file_path)
        assert expected_tool in content, f"Expected '{expected_tool}' in {file_path}, but it was not found"

    @pytest.mark.parametrize(
        ("file_path", "expected_text"),
        [("agents/vm-pilot.md", "JOB_ID"), ("agents/vm-pilot-inspector.md", "JOB_ID")],
        ids=["vm-pilot-JOB_ID", "vm-pilot-inspector-JOB_ID"],
    )
    def test_agent_contains_job_id_reference(self, file_path: str, expected_text: str) -> None:
        """Each agent must reference JOB_ID for lifecycle correlation.

        Args:
            file_path: Path to the agent .md file relative to repo root.
            expected_text: Text that must appear in the file.
        """
        content = _read_skill(file_path)
        assert expected_text in content, f"Expected '{expected_text}' in {file_path}, but it was not found"


class TestPluginJsonPaths:
    """Verify all skill paths in plugin.json resolve to existing directories."""

    def test_all_skill_paths_resolve(self) -> None:
        """Every entry in plugin.json's skills array must be an existing directory."""
        plugin_path = REPO_ROOT / ".claude-plugin" / "plugin.json"
        assert plugin_path.exists(), f"plugin.json not found at {plugin_path}"

        data = json.loads(plugin_path.read_text())
        skills = data.get("skills", [])
        assert len(skills) >= 7, f"Expected at least 7 skills in plugin.json, got {len(skills)}"

        missing: list[str] = []
        for skill_path in skills:
            full_path = REPO_ROOT / skill_path
            if not full_path.is_dir():
                missing.append(skill_path)

        assert not missing, f"plugin.json skill paths that do not resolve: {missing}"

    def test_plugin_json_includes_expected_skills(self) -> None:
        """plugin.json must include vm-fleet-ops, vm-scenario-runner, packer-prerequisites."""
        plugin_path = REPO_ROOT / ".claude-plugin" / "plugin.json"
        data = json.loads(plugin_path.read_text())
        skills_text = " ".join(data.get("skills", []))

        for expected in ("vm-fleet-ops", "vm-scenario-runner", "packer-prerequisites"):
            assert expected in skills_text, f"Expected '{expected}' in plugin.json skills array"


class TestVideoEnabledWorkflowMarkers:
    """Verify video-enabled proof run workflow markers in skills and agents.

    These tests enforce the delegated execution path for video-enabled runs:
    - Orchestrator coordinates and reports (does not touch VM directly)
    - Pilot executes via MCP tools (owns VM interaction)
    - Video intent propagates through handoff surfaces for downstream slices
    """

    @pytest.mark.parametrize(
        ("file_path", "expected_text"),
        [
            ("skills/vm-scenario-runner/SKILL.md", "video=True"),
            ("skills/vm-scenario-runner/SKILL.md", "VIDEO: {video}"),
            ("skills/vm-scenario-runner/SKILL.md", "`video` — boolean"),
            ("skills/vm-ground-control/SKILL.md", "VIDEO: <true or false"),
            ("skills/vm-ground-control/SKILL.md", "Video intent propagation"),
            ("agents/vm-pilot.md", "`VIDEO` for video-intent propagation"),
            ("agents/vm-pilot.md", "VIDEO: <true or false"),
        ],
        ids=[
            "scenario-runner-video-param",
            "scenario-runner-video-in-dispatch-prompt",
            "scenario-runner-video-receipt-field",
            "ground-control-video-in-prompt-shape",
            "ground-control-video-propagation-section",
            "vm-pilot-video-in-intro",
            "vm-pilot-video-in-return-format",
        ],
    )
    def test_video_workflow_marker_present(self, file_path: str, expected_text: str) -> None:
        """Each file must contain the specified video workflow marker.

        Args:
            file_path: Path to the skill/agent file relative to repo root.
            expected_text: Text that must appear in the file.
        """
        content = _read_skill(file_path)
        assert expected_text in content, f"Expected '{expected_text}' in {file_path}, but it was not found"

    def test_vm_ground_control_video_section_exists(self) -> None:
        """vm-ground-control must have a Video-Enabled Proof Runs section."""
        content = _read_skill("skills/vm-ground-control/SKILL.md")
        assert "## Video-Enabled Proof Runs" in content, (
            "Expected '## Video-Enabled Proof Runs' section in vm-ground-control"
        )

    def test_video_metadata_table_exists(self) -> None:
        """vm-ground-control must document video metadata for downstream slices."""
        content = _read_skill("skills/vm-ground-control/SKILL.md")
        assert "Metadata for downstream slices" in content, (
            "Expected 'Metadata for downstream slices' table in vm-ground-control"
        )
        assert "video:{ck}` session key" in content, "Expected session key pattern in metadata table"

    def test_orchestrator_does_not_capture_screenshots(self) -> None:
        """vm-ground-control must state orchestrator does not capture screenshots in video runs."""
        content = _read_skill("skills/vm-ground-control/SKILL.md")
        assert "does **not** capture screenshots" in content or ("does not capture screenshots" in content), (
            "Expected orchestrator constraint about not capturing screenshots"
        )

    def test_pilot_echoes_video_for_correlation(self) -> None:
        """vm-pilot must document echoing VIDEO back for correlation."""
        content = _read_skill("agents/vm-pilot.md")
        assert "echo" in content.lower(), "Expected vm-pilot to mention 'echo' for VIDEO correlation"
        assert "VIDEO" in content, "Expected vm-pilot to document VIDEO field for correlation"
