# SPDX-FileCopyrightText: 2026 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Generated by datamodel-codegen:
#   source filename:  blender_asset_library_openapi.yaml

from __future__ import annotations

from dataclasses import dataclass
from enum import StrEnum
from typing import Any


@dataclass
class Contact:
    """Owner / publisher of this asset library."""

    name: str
    url: str | None = None
    email: str | None = None


@dataclass
class URLWithHash:
    """Resource that's identified by a URL.

    The resource should be fetched by including the hash in the query
    string, like `GET {URL}?hash={HASH}`. Here `{HASH}` should _not_
    include the hash type. The purpose of including this on the URL is
    for cache busting, and thus the hash type is not relevant here.
    """

    url: str
    """URL of the page file."""

    hash: str
    """Hash of the resource obtained at that URL.

    This should be in the format "HASHTYPE:HASH-AS-HEX". Currently only
    the "SHA256" hash type is supported. Note that for dynamic API
    servers, which may perform a server-side filter on the data, the
    actual response may not have the same hash. Static servers send
    content that matches the hash.
    """


type AssetIDTypeV1 = str
"""Type of the Blender data-block.

This can be obtained via BPY with `datablock.id_type`. Any comparisons
should be done in a case-insensitive manner. Note that this list is just
a list of data-block types in Blender. This type being in this list does
not mean that Blender supports making this data-block an asset. It's
just here to ensure that if that changes, and more data-block types can
become assets, this schema doesn't need updating.
"""


class CustomPropertyTypeV1(StrEnum):
    """Type of IDProperty, see `eIDPropertyType` in `DNA_ID_enumms.h`.

    For now, type `ID` and `IDPARRAY` are not supported.
    """

    IDP_STRING = "IDP_STRING"
    IDP_INT = "IDP_INT"
    IDP_FLOAT = "IDP_FLOAT"
    IDP_ARRAY = "IDP_ARRAY"
    IDP_GROUP = "IDP_GROUP"
    IDP_DOUBLE = "IDP_DOUBLE"
    IDP_BOOL = "IDP_BOOL"


@dataclass
class AssetBlenderVersionsV1:
    """Minimum and (optionally) maximum versions of Blender that this asset
    should be shown in.

    This is a half-open interval: Blender shows the asset if `min <= blender < until`.
    """

    min: str
    """Minimum version of Blender that should show this asset."""

    until: str | None = None
    """First version of Blender that should NOT show this asset."""


@dataclass
class CatalogV1:
    """An asset catalog, which can be represented by one or more UUIDs."""

    path: str
    uuids: list[str]
    simple_name: str | None = None


@dataclass
class FileV1:
    """Single file in the asset library.

    Identified by its relative path in that library.
    """

    path: str
    """Relative path of where this file is located in the asset library."""

    size_in_bytes: int
    hash: str
    """Hash of the file.

    This should be in the format "HASHTYPE:HASH-AS-HEX". Currently only
    the "SHA256" hash type is supported.
    """

    blender_version: str
    """Version of Blender used to write this file.

    Only contains the major and minor version, no patch version ("5.2",
    "6.3", etc. but not "5.2.1").
    """

    url: str | None = None
    """URL where the file can be downloaded.

    If the URL is relative, it is to be interpreted as relative to the
    library's root URL. If the URL is not given, or an empty string, it
    is assumed to be the same as 'path'.
    """


@dataclass
class AssetLibraryMeta:
    """Meta-data of this asset library."""

    api_versions: dict[str, URLWithHash]
    """API versions of this asset library.

    This is reflected in the URLs of all OpenAPI operations except the
    one to get this metadata. A single asset library can expose multiple
    versions, in order to be backward-compatible with older versions of
    Blender. Keys should be "v1", "v2", etc. and their values should be
    a URLWithHash that points to each version's index file.
    """

    name: str
    """Name of this asset library."""

    contact: Contact


@dataclass
class AssetLibraryIndexV1:
    """The available assets at this library."""

    schema_version: str
    """Version number of the used schema.

    This should be the same as the version of this OpenAPI definition,
    as described in its 'info.version' field.
    """

    asset_size_bytes: int
    asset_count: int
    """Total number of assets in this index.

    This is the sum of all `asset_count` fields of each page.
    """

    file_count: int
    """Total number of files in this index.

    This is the sum of all `file_count` fields of each page (after
    deduplication).
    """

    pages: list[URLWithHash]
    """URLs of the individual asset index pages.

    When relative, these are taken as relative to the main server URL
    (i.e. the root of all paths defined in this OpenAPI spec).
    """

    catalogs: list[CatalogV1] | None = None


@dataclass
class AssetLibraryIndexPageV1:
    """Any number of assets."""

    asset_count: int
    """Number of assets in this page.

    This is declared separately, so that a partial JSON parser has this
    information before the entire file is downloaded and parsed.
    """

    file_count: int
    """Number of files in this page.

    This is declared separately, so that a partial JSON parser has this
    information before the entire file is downloaded and parsed.
    """

    assets: list[AssetV1]
    files: list[FileV1]
    """The files that are referenced by the above assets.

    Note that there may be duplication of this information between asset
    pages, as each file can contain multiple assets, and those assets
    might be scattered across multiple pages.
    """


@dataclass
class AssetV1:
    """Representation of a single asset.

    Assets are always Blender data-blocks in some blend file. This asset
    may be stored in the same blend file as other assets, and so it does
    _not_ represent a single downloadable item.
    """

    name: str
    """Name of the Blender data-block."""

    id_type: AssetIDTypeV1
    files: list[str]
    """Relative paths of the files that contain this asset.

    The first entry in the list MUST contain the asset data-block
    itself, while the remaining entries can be in any order. These
    relative paths are used to look up more file information in the
    asset library's list of files.
    """

    bl_versions: AssetBlenderVersionsV1
    thumbnail: URLWithHash | None = None
    meta: AssetMetadataV1 | None = None


@dataclass
class AssetMetadataV1:
    """Metadata of an asset, as defined by Blender's `AssetMeta` DNA struct.

    Fields should either be non-empty or absent.
    """

    catalog_id: str | None = None
    """The catalog UUID that contains this asset.

    Having the UUID here makes it easier to create a per-blendfile
    .cats.txt file, if that's ever necessary.
    """

    preferred_import_method: str | None = None
    """The import method preferred by this asset.

    For example, base meshes for sculpting can declare they should
    always be appended, making them instantly usable for sculpting.
    Supports values APPEND, APPEND_REUSE, and ASSET_IMPORT_PACK. These
    are not modeled here as an enum, to aid in forward compatibility of
    this Blender version with future import methods (it'll just ignore
    unsupported methods, instead of rejecting the file as invalid).
    """

    tags: list[str] | None = None
    author: str | None = None
    description: str | None = None
    license: str | None = None
    copyright: str | None = None
    properties: CustomPropertiesV1 | None = None


type CustomPropertiesV1 = list[CustomPropertyV1]
"""Arbitrary custom properties of the asset.

Keys are the property names.
"""


@dataclass
class CustomPropertyV1:
    """Single 'custom property' value of the asset.

    The value should be compatible with the given type; GROUP properties
    should be represented as `CustomPropertiesV1` object again. Arrays
    should specify an `itemtype`.
    """
    name: str
    type: CustomPropertyTypeV1
    value: CustomPropertiesV1 | list[Any] | float | int | str | bool
    itemtype: CustomPropertyTypeV1 | None = None
