"""
Pydantic base model for MAML version 1.1
"""

# generated by datamodel-codegen:
# filename:  v1p1.json
# timestamp: 2025-09-16T01:55:16+00:00
# datamodel-codegen --input schemas/v1p1.json --input-file-type jsonschema --output model_v1p1.py

from __future__ import annotations

from datetime import date as date_aliased
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Field
from astropy.io.votable.ucd import check_ucd


class DOIEntry(BaseModel):
    """
    DOI field that holds the DOI and the type of DOI.
    """

    DOI: str = Field(..., description="Valid DOI")
    type: str = Field(..., description="Type of DOI")


class DependEntry(BaseModel):
    """
    Depends field that tells you what tables the meta data depends on.
    """

    survey: Optional[str] = Field(None, description="The name of the dependent survey.")
    dataset: Optional[str] = Field(
        None, description="The name of the dependent dataset."
    )
    table: str = Field(..., description="The name of the dependent table.")
    version: Optional[Union[str, float]] = Field(
        None, description="The version of the dependent table."
    )


class KeyValueEntry(BaseModel):
    """
    Allowing Key-value entries into the meta data. Main change from v1.0
    """

    key: str = Field(..., description="Key name")
    value: Union[Union[float, str], List[Union[float, str]]] = Field(
        ..., description="Value/s of key"
    )
    comment: str = Field(..., description="Description of key")


class QCEntry(BaseModel):
    """
    Quality Control field that allows for min/max checks during data validation.
    """

    min: Optional[Union[float, str]] = None
    max: Optional[Union[float, str]] = None
    miss: Optional[Union[float, str]] = None


class FieldEntry(BaseModel):
    """
    Fields field describing the columns of the table.
    """

    name: str = Field(..., description="Required field name")
    unit: Optional[str] = Field(None, description="Recommended unit of measurement")
    info: Optional[str] = Field(None, description="Recommended short description")
    ucd: Optional[Union[str, List[str]]] = Field(
        None, description="Recommended UCD string"
    )
    data_type: str = Field(
        ..., description="Required data type (e.g., int32, string, bool, double)"
    )
    array_size: Optional[Union[int, str]] = Field(
        None, description="Optional max length of string"
    )
    qc: Optional[QCEntry] = Field(
        None, description="Optional quality control parameters"
    )

    def __post_init__(self):
        """
        Checking that the ucd, if it exists, is valid.
        """
        if self.ucd is not None:
            check_ucd(self.ucd)


class V1P1(BaseModel):
    """Pydantic Base model for version 1.0"""

    class Config:
        """Setting configuration. Not allowing extra fields"""

        extra = "forbid"

    survey: Optional[str] = Field(None, description="Optional survey name")
    dataset: Optional[str] = Field(None, description="Recommended dataset name")
    table: str = Field(..., description="Required table name")
    version: Union[str, float] = Field(
        ..., description="Required version (string, integer, or float)"
    )
    date: date_aliased = Field(
        ..., description="Required date in YYYY-MM-DD format (ISO-8601)"
    )
    author: str = Field(..., description="Required lead author name and <email>")
    coauthors: Optional[Union[str, List[str]]] = Field(
        None, description="Optional coauthor name and optionally <email>"
    )
    DOIs: Optional[List[DOIEntry]] = None
    depends: Optional[List[DependEntry]] = None
    description: Optional[str] = Field(
        None, description="Recommended short description of the table"
    )
    comments: Optional[Union[str, List[str]]] = Field(
        None, description="Optional comment or interesting fact"
    )
    license: Optional[str] = Field(None, description="Recommended license for the data")
    keywords: Optional[Union[str, List[str]]] = Field(
        None, description="Optional keyword tag"
    )
    keyarray: Optional[List[KeyValueEntry]] = None
    extra: Optional[Dict[str, Any]] = None
    MAML_version: float = Field(
        1.1, literal=True, description="Optional version of the MAML schema"
    )
    fields: List[FieldEntry]
