"""Metric computation for benchmark results."""

from __future__ import annotations

from cohort.benchmark.code_runner import evaluate_task
from cohort.benchmark.config import CodingTask, StrategyResult, TaskMetrics
from cohort.meeting import extract_keywords


def compute_metrics(result: StrategyResult, task: CodingTask) -> TaskMetrics:
    """Compute all metrics for a strategy result on a task."""
    metrics = TaskMetrics(
        strategy_name=result.strategy_name,
        task_id=task.task_id,
        total_tokens=result.token_usage.total_tokens,
        api_calls=result.token_usage.api_calls,
        turn_count=len(result.turns),
        elapsed_seconds=result.elapsed_seconds,
    )

    # Run code against test cases
    if result.final_code:
        sample_results, hidden_results = evaluate_task(result.final_code, task)

        metrics.sample_total = len(sample_results)
        metrics.sample_passed = sum(1 for r in sample_results if r.passed)
        metrics.hidden_total = len(hidden_results)
        metrics.hidden_passed = sum(1 for r in hidden_results if r.passed)
    else:
        metrics.sample_total = len(task.sample_cases)
        metrics.hidden_total = len(task.hidden_cases)

    # Failure mode detection
    metrics.planning_paralysis = "planning_paralysis" in " ".join(result.failure_modes)

    # Loop detection from turns
    prev_keywords: set[str] = set()
    for turn in result.turns:
        keywords = set(extract_keywords(turn.content))
        if prev_keywords and keywords:
            overlap = len(keywords & prev_keywords) / max(len(keywords), 1)
            if overlap > 0.8:
                metrics.loop_count += 1
            if overlap > 0.6:
                metrics.duplication_count += 1
        prev_keywords = keywords

    return metrics
