from __future__ import annotations

from http import HTTPStatus

from pydantic import BaseModel as PydanticBaseModel
from pydantic import ConfigDict, Field, SerializeAsAny

Loc = list[str | int]


class BaseModel(PydanticBaseModel):
    """
    Base model for the diagnostic pydantic models.
    """

    model_config = ConfigDict(extra="forbid")


class DiagnosticError(BaseModel):
    """
    Base class for all diagnostic errors.
    """

    model_config = ConfigDict(extra="allow")

    # This is intentionally protected, as Pydantic does not export protected members to OpenAPI schema,
    # and that is exactly what we want. Status code is not part of the JSON response, but it represents
    # HTTP status code of the error response.
    _status_code: int = HTTPStatus.UNPROCESSABLE_ENTITY

    loc: Loc = Field(default_factory=list, title="Error location")
    msg: str = Field(title="Descriptive error message")
    type: str = Field(title="Programatic error type")


class DiagnosticResponse(BaseModel):
    """
    Response returned to user, when any diagnostic error is collected.
    """

    detail: list[SerializeAsAny[DiagnosticError]] = Field(default_factory=list)
