"""CPU-only contracts for benchmark visualization generation."""

from __future__ import annotations

import matplotlib.pyplot as plt
import pytest

from obliteratus.evaluation import benchmark_plots as plots


@pytest.fixture
def results():
    return [
        {
            "method": "advanced",
            "model": "org/model-a",
            "model_short": "model-a",
            "perplexity": 10.0,
            "refusal_rate": 0.1,
            "coherence": 0.9,
            "time_s": 2.0,
            "strong_layers": 3,
            "ega_expert_dirs": 2,
            "cot_preserved": 1,
            "expert_classified_layers": 4,
        },
        {
            "method": "unknown/hf_secret123456",
            "model": "org/model-b",
            "perplexity": 12.0,
            "refusal_rate": 0.2,
            "coherence": 0.8,
            "time_s": 3.0,
            "strong_layers": 0,
            "ega_expert_dirs": 0,
            "cot_preserved": 0,
            "ega_safety_layers": 0,
        },
    ]


def test_label_sanitization_and_palette_fallback():
    label = plots._sanitize_label(
        "/private/path/model hf_secret123456 0123456789abcdef0123456789abcdef", max_len=40,
    )
    assert "/private/path" not in label
    assert "hf_secret" not in label
    assert label == "model <TOKEN> <REDACTED>"
    assert plots._get_color("basic") == plots.PALETTE["basic"]
    assert plots._get_color("custom", 9) == plots.MODEL_PALETTE[1]


@pytest.mark.parametrize(
    "factory",
    [
        plots.plot_pareto_frontier,
        plots.plot_method_radar,
        plots.plot_metric_bars,
        plots.plot_timing_efficiency,
        plots.plot_moe_metrics,
        plots.plot_model_scaling,
    ],
)
def test_each_plot_returns_a_figure_for_empty_input(factory):
    figure = factory([])
    assert isinstance(figure, plt.Figure)
    plt.close(figure)


@pytest.mark.parametrize(
    "factory",
    [
        plots.plot_pareto_frontier,
        plots.plot_method_radar,
        plots.plot_metric_bars,
        plots.plot_timing_efficiency,
        plots.plot_moe_metrics,
        plots.plot_model_scaling,
    ],
)
def test_each_plot_renders_synthetic_results(factory, results):
    figure = factory(results, " — fixture")
    assert isinstance(figure, plt.Figure)
    assert figure.axes
    plt.close(figure)


def test_pareto_handles_single_point_without_frontier_line(results):
    figure = plots.plot_pareto_frontier(results[:1])
    assert isinstance(figure, plt.Figure)
    plt.close(figure)


def test_moe_plot_handles_non_moe_results(results):
    figure = plots.plot_moe_metrics(results[1:])
    assert "No MoE-specific features" in figure.axes[0].texts[0].get_text()
    plt.close(figure)


def test_dashboard_modes_and_optional_moe_panel(results):
    assert plots.generate_benchmark_dashboard([]) == []
    method_figures = plots.generate_benchmark_dashboard(results, mode="multi_method")
    model_figures = plots.generate_benchmark_dashboard(results, mode="multi_model")
    assert len(method_figures) == 5
    assert len(model_figures) == 5
    assert plots.generate_benchmark_dashboard(results, mode="unsupported") == []
    for figure in method_figures + model_figures:
        plt.close(figure)
