"""Validate NDJSON events against the application-owned wire schemas."""

import json
import sys
from importlib import import_module
from pathlib import Path
from types import ModuleType

from pydantic import BaseModel, TypeAdapter

BACKEND_ROOT = Path(__file__).parents[1] / "backend"
EVENT_CLASS_NAMES = {
    "metadata": "MetadataEvent",
    "track": "TrackEvent",
    "warning": "WarningEvent",
    "error": "ErrorEvent",
    "done": "DoneEvent",
}


def validate_event(line: str) -> BaseModel:
    """Parse one complete line with exact fields and strict value types."""
    schemas = _load_schemas()
    payload = json.loads(line)
    if not isinstance(payload, dict):
        raise ValueError("NDJSON event must be an object")
    event_type = payload.get("type")
    if not isinstance(event_type, str) or event_type not in EVENT_CLASS_NAMES:
        raise ValueError("NDJSON event has an unknown type")
    event_class = getattr(schemas, EVENT_CLASS_NAMES[event_type])
    if set(payload) != set(event_class.model_fields):
        raise ValueError(f"{event_type} event fields do not match the wire schema")
    if event_type == "track":
        track = payload.get("track")
        track_class = schemas.TrackCard
        if not isinstance(track, dict) or set(track) != set(track_class.model_fields):
            raise ValueError("track card fields do not match the wire schema")
    adapter: TypeAdapter[BaseModel] = TypeAdapter(schemas.StreamEvent)
    return adapter.validate_json(line, strict=True)


def _load_schemas() -> ModuleType:
    backend_path = str(BACKEND_ROOT)
    if backend_path not in sys.path:
        sys.path.insert(0, backend_path)
    return import_module("app.api.schemas")
