"""E2E agent tests — send prompts to claude -p and evaluate responses.

Run with:
    uv run pytest tests/e2e/ -v -m e2e

These tests call claude -p as a subprocess, so they:
  - Require the `claude` CLI to be installed
  - Use real API credits (haiku by default, ~$0.01/test)
  - Are slow (~5-30s per test)
  - Are marked with @pytest.mark.e2e and skipped by default
"""

from __future__ import annotations

from pathlib import Path

import pytest
import yaml

from .conftest import run_agent
from .evaluator import (
    assert_any_keyword_in_result,
    assert_keywords_in_result,
    assert_language,
    assert_tool_called,
    assert_tool_not_called,
)

# Load test cases from YAML
_CASES_PATH = Path(__file__).parent / "test_cases.yaml"
with open(_CASES_PATH) as f:
    _ALL_CASES = yaml.safe_load(f)

# Build parametrize ids
_CASE_IDS = [case["id"] for case in _ALL_CASES]


@pytest.mark.e2e
@pytest.mark.parametrize("case", _ALL_CASES, ids=_CASE_IDS)
def test_agent(case: dict) -> None:
    """Run a single e2e test case against claude -p."""
    result = run_agent(case["prompt"])

    # Should not error
    assert not result.is_error, (
        f"Agent returned an error: {result.error_message}"
    )

    # Should have a non-empty response
    assert result.result_text, "Agent returned empty result text"

    # Check expected tools were called
    for tool in case.get("expected_tools", []):
        assert_tool_called(result, tool)

    # Check unexpected tools were NOT called
    for tool in case.get("unexpected_tools", []):
        assert_tool_not_called(result, tool)

    # Check all required keywords present
    if case.get("expected_keywords"):
        assert_keywords_in_result(result, case["expected_keywords"])

    # Check at least one optional keyword present
    if case.get("any_keywords"):
        assert_any_keyword_in_result(result, case["any_keywords"])

    # Check response language
    if case.get("language"):
        assert_language(result, case["language"])
