"""
End-to-end smoke-tests for the personality tasks.

We monkey-patch the dataset loaders so the tests stay offline, quick and
deterministic while still exercising the full Task construction path.
"""

from inspect_ai.dataset import Sample
from inspect_ai.dataset._dataset import MemoryDataset

import inspect_evals.personality.personality as personality

# --------------------------------------------------------------------------- #
# Helpers: stub datasets
# --------------------------------------------------------------------------- #


def _stub_bfi_dataset() -> MemoryDataset:
    """A single-question Big-Five dataset."""
    mapping = {"A": 1, "B": 2, "C": 3, "D": 4, "E": 5}
    samples = [
        Sample(
            input="I see myself as someone who is reserved.",
            choices=[
                "Disagree",
                "Somewhat disagree",
                "Neutral",
                "Somewhat agree",
                "Agree",
            ],
            target=["A", "B", "C", "D", "E"],
            metadata={"trait": "Extraversion", "answer_mapping": mapping},
        ),
    ]
    return MemoryDataset(samples)


def _stub_trait_dataset() -> MemoryDataset:
    """A single-question TRAIT sample (Conscientiousness)."""
    mapping = {"A": 1, "B": 1, "C": 0, "D": 0}
    samples = [
        Sample(
            input="I finish whatever I begin.",
            choices=[
                "Strongly agree",
                "Agree",
                "Disagree",
                "Strongly disagree",
            ],
            target=["A", "B", "C", "D"],
            metadata={"trait": "Conscientiousness", "answer_mapping": mapping},
        ),
    ]
    return MemoryDataset(samples)


# --------------------------------------------------------------------------- #
# Tests
# --------------------------------------------------------------------------- #


def test_task_bfi(monkeypatch):
    """personality_BFI wires up dataset, solver, scorer and metric."""
    # replace GitHub fetcher with tiny in-memory dataset
    monkeypatch.setattr(personality, "load_dataset", lambda name: _stub_bfi_dataset())

    task = personality.personality_BFI()

    assert len(task.dataset) == 1
    assert task.solver, "solver list should not be empty"
    assert task.scorer is not None
    assert any(
        callable(m) and m.__qualname__.startswith("trait_ratio") for m in task.metrics
    )


def test_task_trait(monkeypatch):
    """
    personality_TRAIT() should combine one sample per split (8 traits) into
    a single dataset and attach the usual solver / scorer / metric objects.
    """  # noqa: D205
    # hf_dataset is called once per trait split; return one-sample dataset
    monkeypatch.setattr(
        personality,
        "hf_dataset",
        lambda path, split, sample_fields, cached: _stub_trait_dataset(),
    )
    # prevent actual HuggingFace login
    monkeypatch.setattr(personality, "hf_login", lambda token=None: None)

    task = personality.personality_TRAIT()

    assert len(task.dataset) == 8  # 8 splits × 1 sample each
    assert task.solver
    assert task.scorer is not None
    assert any(
        callable(m) and m.__qualname__.startswith("trait_ratio") for m in task.metrics
    )
