"""Immutable Music DNA vector and metadata.

This module defines :class:`MusicDNAVectorMetadata` and
:class:`MusicDNAVector`, the fixed-size numerical representation
produced by the Music DNA Encoder.

The vector is a read-only ``numpy.ndarray`` with dtype ``float32``
and shape ``(512,)``.
"""

from __future__ import annotations

from dataclasses import dataclass

import numpy as np


@dataclass(frozen=True)
class MusicDNAVectorMetadata:
    """Immutable metadata about how a MusicDNAVector was encoded.

    Attributes:
        encoder_version: Semantic version of the MusicDNAEncoder.
        layout_version: Semantic version of the MusicDNALayout.
        created_at: ISO 8601 UTC timestamp string.
        feature_count: Number of features written into the vector.
        reserved_dimensions: Number of dimensions filled with 0.0.
    """

    encoder_version: str
    layout_version: str
    created_at: str
    feature_count: int
    reserved_dimensions: int


@dataclass(frozen=True)
class MusicDNAVector:
    """Immutable fixed-size numerical representation of a track.

    Attributes:
        track_id: UUID of the track this vector represents.
        schema_version: Music DNA schema version (e.g. ``"1.0"``).
        dimension: Total vector dimension (always 512).
        values: Read-only ``numpy.ndarray`` with dtype ``float32``
            and shape ``(512,)``.
        metadata: :class:`MusicDNAVectorMetadata` with encode provenance.
    """

    track_id: str
    schema_version: str
    dimension: int
    values: np.ndarray
    metadata: MusicDNAVectorMetadata

    def __post_init__(self) -> None:
        """Make the values array read-only."""
        self.values.flags.writeable = False
