"""Tests for utility functions."""

import json
import tempfile
from pathlib import Path

import pytest

from agent_preflight.utils import render_prompt, summarize_run


# ---------------------------------------------------------------------------
# render_prompt
# ---------------------------------------------------------------------------


class TestRenderPrompt:
    def test_basic_substitution(self):
        with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f:
            f.write("Budget: {BUDGET_USD} | Task: {TASK_NAME}")
            f.flush()
            result = render_prompt(f.name, BUDGET_USD="0.50", TASK_NAME="golf")
        assert result == "Budget: 0.50 | Task: golf"

    def test_missing_variable_raises(self):
        with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f:
            f.write("Budget: {BUDGET_USD}")
            f.flush()
            with pytest.raises(KeyError, match="BUDGET_USD"):
                render_prompt(f.name)

    def test_file_not_found(self):
        with pytest.raises(FileNotFoundError):
            render_prompt("/nonexistent/template.md", X="1")

    def test_no_placeholders(self):
        with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f:
            f.write("Plain text, no substitution.")
            f.flush()
            result = render_prompt(f.name)
        assert result == "Plain text, no substitution."

    def test_literal_braces_escaped(self):
        """Double braces {{}} should produce literal braces."""
        with tempfile.NamedTemporaryFile(mode="w", suffix=".md", delete=False) as f:
            f.write("JSON: {{'key': {VALUE}}}")
            f.flush()
            result = render_prompt(f.name, VALUE="42")
        assert result == "JSON: {'key': 42}"


# ---------------------------------------------------------------------------
# summarize_run
# ---------------------------------------------------------------------------


def _make_run(tmp, models):
    """Create a fake run directory with summary.json files."""
    run_dir = Path(tmp) / "test-run"
    for alias, data in models.items():
        model_dir = run_dir / alias
        model_dir.mkdir(parents=True)
        (model_dir / "summary.json").write_text(json.dumps(data))
    return run_dir


class TestSummarizeRun:
    def test_basic_aggregation(self):
        with tempfile.TemporaryDirectory() as tmp:
            run_dir = _make_run(tmp, {
                "model-a": {
                    "cost_usd": 0.10,
                    "tool_calls": 5,
                    "cache": {"cached_tokens": 1000, "total_prompt_tokens": 2000},
                },
                "model-b": {
                    "cost_usd": 0.20,
                    "tool_calls": 10,
                    "cache": {"cached_tokens": 500, "total_prompt_tokens": 1000},
                },
            })
            s = summarize_run(run_dir)
            assert s["total_cost"] == 0.30
            assert s["total_tools"] == 15
            assert s["cached_tokens"] == 1500
            assert s["cache_hit_rate"] == pytest.approx(1500 / 3000)
            assert s["errors"] == []

    def test_null_cost_does_not_crash(self):
        """The Codex review bug: cost_usd=null should not break aggregation."""
        with tempfile.TemporaryDirectory() as tmp:
            run_dir = _make_run(tmp, {
                "model-a": {"cost_usd": None, "tool_calls": 3},
                "model-b": {"cost_usd": 0.15, "tool_calls": 7},
            })
            s = summarize_run(run_dir)
            assert s["total_cost"] == 0.15
            assert s["total_tools"] == 10

    def test_errors_collected(self):
        with tempfile.TemporaryDirectory() as tmp:
            run_dir = _make_run(tmp, {
                "good": {"cost_usd": 0.10},
                "bad": {"cost_usd": 0.05, "error": "ejected: budget"},
            })
            s = summarize_run(run_dir)
            assert len(s["errors"]) == 1
            assert s["errors"][0] == ("bad", "ejected: budget")

    def test_empty_run_dir(self):
        with tempfile.TemporaryDirectory() as tmp:
            run_dir = Path(tmp) / "empty-run"
            run_dir.mkdir()
            s = summarize_run(run_dir)
            assert s["total_cost"] == 0.0
            assert s["total_tools"] == 0
            assert s["cache_hit_rate"] == 0.0

    def test_missing_cache_data(self):
        with tempfile.TemporaryDirectory() as tmp:
            run_dir = _make_run(tmp, {
                "model": {"cost_usd": 0.10, "tool_calls": 5},
            })
            s = summarize_run(run_dir)
            assert s["cache_hit_rate"] == 0.0
            assert s["cached_tokens"] == 0
