"""Utility functions for agent-preflight."""

from __future__ import annotations

import string
from pathlib import Path


def render_prompt(template_path: str | Path, **variables: str) -> str:
    """Render a prompt template with variable substitution.

    Supports {VAR_NAME} style substitution (case-sensitive). Useful for
    parameterizing agent prompts with budget, task, or environment variables.

    Args:
        template_path: Path to template file (text, with {VAR} placeholders).
        **variables: Keyword arguments to substitute into the template.

    Returns:
        Rendered prompt text with all variables substituted.

    Raises:
        KeyError: If a placeholder in the template has no matching variable.
        FileNotFoundError: If the template file doesn't exist.

    Example::

        prompt = render_prompt(
            "task.md",
            BUDGET_USD="0.50",
            BUDGET_TOKENS="100000",
            TASK_NAME="code-golf",
        )
    """
    content = Path(template_path).read_text()
    formatter = string.Formatter()
    # Validate that all placeholders have values
    try:
        return content.format(**variables)
    except KeyError as e:
        raise KeyError(f"Missing template variable: {e.args[0]}")


def summarize_run(run_dir: Path) -> dict:
    """Summarize a completed run for quick analysis.

    Reads summary.json files from all model directories and aggregates:
    - Total cost
    - Cache statistics
    - Tool call counts
    - Error summary

    Returns a dict with aggregated metrics.
    """
    import json
    from pathlib import Path

    total_cost = 0.0
    total_tools = 0
    total_cache_tokens = 0
    total_prompt_tokens = 0
    errors = []

    for model_dir in sorted(run_dir.iterdir()):
        if not model_dir.is_dir():
            continue

        summary_path = model_dir / "summary.json"
        if not summary_path.exists():
            continue

        try:
            s = json.loads(summary_path.read_text())
            total_cost += s.get("cost_usd") or 0
            total_tools += s.get("tool_calls") or 0

            cache = s.get("cache", {})
            if isinstance(cache, dict):
                total_cache_tokens += cache.get("cached_tokens", 0)
                total_prompt_tokens += cache.get("total_prompt_tokens", 0)

            if s.get("error"):
                errors.append((model_dir.name, s["error"]))
        except Exception:
            pass

    cache_hit_rate = 0.0
    if total_prompt_tokens > 0:
        cache_hit_rate = total_cache_tokens / total_prompt_tokens

    return {
        "total_cost": round(total_cost, 4),
        "total_tools": total_tools,
        "cache_hit_rate": round(cache_hit_rate, 4),
        "cached_tokens": total_cache_tokens,
        "errors": errors,
    }
