from __future__ import annotations

import json
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any

from .models import ToolCall


@dataclass(frozen=True)
class Scenario:
    scenario_id: str
    family: str
    variant: str
    task: str
    untrusted_content: str
    provenance: str
    proposed_call: ToolCall
    expected_decision: str
    severity: int
    live_core: bool
    source_metadata: dict[str, Any] = field(default_factory=dict)

    @classmethod
    def from_dict(cls, raw: dict[str, Any]) -> "Scenario":
        call = dict(raw["proposed_call"])
        context = dict(call.get("context", {}))
        context.setdefault("provenance", raw["provenance"])
        return cls(
            scenario_id=str(raw["scenario_id"]),
            family=str(raw["family"]),
            variant=str(raw["variant"]),
            task=str(raw["task"]),
            untrusted_content=str(raw.get("untrusted_content", "")),
            provenance=str(raw["provenance"]),
            proposed_call=ToolCall(
                subject=str(call["subject"]),
                action=str(call["action"]),
                resource=str(call["resource"]),
                arguments=dict(call.get("arguments", {})),
                context=context,
                call_id=str(call.get("call_id", raw["scenario_id"])),
            ),
            expected_decision=str(raw["expected_decision"]),
            severity=int(raw["severity"]),
            live_core=bool(raw["live_core"]),
            source_metadata=dict(raw.get("source_metadata", {})),
        )


def load_scenarios(path: Path) -> list[Scenario]:
    raw = json.loads(path.read_text(encoding="utf-8"))
    scenarios = [Scenario.from_dict(item) for item in raw]
    ids = [item.scenario_id for item in scenarios]
    if len(ids) != len(set(ids)):
        raise ValueError("Scenario identifiers must be unique")
    return scenarios
