"""Benchmark runner — executes all scenarios and collects results."""

import json
import os
from datetime import datetime
from pathlib import Path
from typing import Optional

from scenarios.base import BenchmarkResult


class BenchmarkRunner:
    """Runs all scenarios and aggregates results."""

    def __init__(self, results_dir: Optional[str] = None):
        self.results_dir = Path(results_dir or "benchmarks/results")
        self.results_dir.mkdir(parents=True, exist_ok=True)

    def run_scenario(self, scenario) -> dict[str, BenchmarkResult]:
        """Run a single scenario for all tools."""
        scenario.setup()
        try:
            scenario.warmup()
            results = scenario.run_all()
        finally:
            scenario.teardown()
        return results

    def run_all_scenarios(self) -> dict[str, dict[str, BenchmarkResult]]:
        """Run all scenarios. Returns {scenario_name: {tool: result}}."""
        all_results = {}

        # Import scenarios dynamically
        from scenarios.navigation import NavigationScenario
        from scenarios.click_performance import ClickScenario
        from scenarios.form_fill import FormFillScenario
        from scenarios.screenshot import ScreenshotScenario
        from scenarios.accessibility_tree import AccessibilityTreeScenario

        scenarios = [
            NavigationScenario(),
            ClickScenario(),
            FormFillScenario(),
            ScreenshotScenario(),
            AccessibilityTreeScenario(),
        ]

        for scenario in scenarios:
            print(f"\n{'='*60}")
            print(f"Running: {scenario.name} ({scenario.description})")
            print(f"{'='*60}")
            try:
                results = self.run_scenario(scenario)
                all_results[scenario.name] = results
                for tool, result in results.items():
                    status = "✅" if result.success_rate == 1.0 else f"⚠️  {result.success_rate:.0%}"
                    print(f"  {tool:20s} {status}  mean={result.mean_ms:8.2f}ms  p95={result.p95_ms:8.2f}ms")
            except Exception as e:
                print(f"  ERROR: {e}")
                all_results[scenario.name] = {}

        return all_results

    def save_results(self, results: dict, label: Optional[str] = None) -> str:
        """Save results to JSON. Returns the file path."""
        timestamp = datetime.utcnow().strftime("%Y%m%d_%H%M%S")
        label_str = f"_{label}" if label else ""
        filename = f"results{timestamp}{label_str}.json"
        filepath = self.results_dir / filename

        # Convert to serializable dict
        serializable = {
            scenario_name: {
                tool: result.to_dict()
                for tool, result in tool_results.items()
            }
            for scenario_name, tool_results in results.items()
        }

        with open(filepath, "w") as f:
            json.dump(serializable, f, indent=2)

        return str(filepath)

    def load_results(self, filepath: str) -> dict:
        """Load results from a JSON file."""
        with open(filepath) as f:
            return json.load(f)
