"""Shared model loading orchestration for predict pipelines."""

from __future__ import annotations

from contextlib import suppress
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any


if TYPE_CHECKING:
    from collections.abc import Callable


@dataclass(frozen=True)
class ModelLoadStrategies:
    """Strategy callbacks for checkpoint/predefined/scratch model loading.

    Each BYOM project injects task-specific loader callbacks while reusing the
    common branching logic.
    """

    from_checkpoint: Callable[[str], Any]
    from_predefined: Callable[[str], Any]
    from_scratch: Callable[[], Any] | None = None


def load_model_with_strategies(action_tracker: Any, strategies: ModelLoadStrategies) -> Any:
    """Load model according to checkpoint -> predefined -> scratch priority."""
    model_checkpoint, predefined_value = action_tracker.get_checkpoint_path()
    if model_checkpoint:
        return strategies.from_checkpoint(model_checkpoint)
    if predefined_value:
        return strategies.from_predefined(predefined_value)
    if strategies.from_scratch is not None:
        return strategies.from_scratch()
    raise ValueError("Neither checkpoint nor predefined model value is available.")


def report_model_load_failure(
    action_tracker: Any,
    *,
    error: Exception,
    status_code: str,
    location: str,
    status_message: str,
    log_prefix: str,
) -> None:
    """Best-effort status and error reporting without raising secondary exceptions."""
    with suppress(Exception):
        action_tracker.update_status(status_code, "ERROR", status_message)

    with suppress(Exception):
        action_tracker.log_error(__file__, location, f"{log_prefix}: {error!s}")
