"""
Dispatch — a thin shim over the shared core (`mizan_core.dispatch`).

The protocol machinery (auth, validation, execution, invalidation, merge, cache)
lives in `mizan_core`; this module re-exports the canonical error taxonomy and
keeps backward-compatible helpers. The router drives `dispatch_call` /
`dispatch_context` directly to get invalidation + origin cache.
"""

from __future__ import annotations

from typing import Any

from mizan_core.dispatch import CacheOrchestrator, DispatchRequest, dispatch_call
from mizan_core.errors import (
    BadRequest,
    ErrorCode,
    Forbidden,
    InternalError,
    MizanError,
    NotFound,
    NotImplementedYet,
    Unauthorized,
    ValidationFailed,
)
from mizan_core.invalidation import resolve_invalidation, resolve_merges

__all__ = [
    "ErrorCode",
    "MizanError",
    "NotFound",
    "BadRequest",
    "ValidationFailed",
    "Unauthorized",
    "Forbidden",
    "NotImplementedYet",
    "InternalError",
    "compute_invalidation",
    "compute_merges",
    "execute_function",
]


_NO_CACHE = CacheOrchestrator(None, None)


def compute_invalidation(view_class: Any, input_data: dict[str, Any] | None) -> list[Any]:
    """`@client(affects=...)` → invalidation list (empty when none). Shared core."""
    return resolve_invalidation(view_class, input_data) or []


def compute_merges(view_class: Any, input_data: dict[str, Any] | None, result: Any) -> list[dict[str, Any]]:
    """`@client(merge=...)` → merge list (empty when none). Shared core."""
    return resolve_merges(view_class, input_data, result) or []


async def execute_function(request: Any, fn_name: str, input_data: dict[str, Any] | None = None) -> Any:
    """Dispatch a function and return its serialized result (auth enforced via core).

    Backward-compat entry point; the router uses `dispatch_call` directly to also
    capture invalidation/merge and run the origin cache.
    """
    identity = getattr(getattr(request, "state", None), "user", None)
    res = await dispatch_call(
        DispatchRequest(identity=identity, args=input_data, native_request=request),
        fn_name,
        _NO_CACHE,
    )
    return res.data
