from __future__ import annotations

from typing import TYPE_CHECKING, TypedDict

if TYPE_CHECKING:
    from edgy.core.db.models.model import Model


class ConfigMarshall(TypedDict, total=False):
    """
    A `TypedDict` for configuring the behavior and serialization aspects of an Edgy `Marshall`.
    Marshalls are used to define how Edgy model data is presented, often for API responses
    or other serialization needs. This configuration allows for fine-grained control
    over which fields are included or excluded, and their read/write properties.

    Attributes:
        model (type[Model] | str):
            **Required**. The Edgy `Model` class or its fully qualified string name
            that this marshall is associated with. The marshall will read data from instances
            of this model.

        fields (list[str] | None):
            An optional list of field names (strings) that *should be included* in the
            serialization output. If provided, only these fields will be present in
            the marshall's data, subject to `exclude` and other filters.
            Defaults to `None`, meaning all fields are considered unless explicitly excluded.

        exclude (list[str] | None):
            An optional list of field names (strings) that *should be excluded* from the
            serialization output. These fields will not appear in the marshall's data.
            Defaults to `None`.

        primary_key_read_only (bool):
            If `True`, makes the primary key fields of the associated model read-only
            within the marshall. This typically means they will be included in serialization
            but will not be settable or modifiable via the marshall's input.
            Defaults to `False`.

        exclude_autoincrement (bool):
            If `True`, automatically excludes fields that are defined as
            `autoincrement` in the associated Edgy model from the marshall's output.
            This is useful for `create` operations where the primary key is
            generated by the database.
            Defaults to `False`.

        exclude_read_only (bool):
            If `True`, post-filters and removes any field that is deemed read-only.
            This includes fields explicitly marked as read-only by the marshall,
            as well as any primary key fields if `primary_key_read_only` is set to `True`.
            This flag is primarily used as a workaround for the lack of a direct `readOnly`
            flag in JSON Schema when `read_only` properties are desired.
            Defaults to `False`.
    """

    model: type[Model] | str
    fields: list[str] | None = None
    exclude: list[str] | None = None
    primary_key_read_only: bool = False
    exclude_autoincrement: bool = False
    exclude_read_only: bool = False
