"""Auto-generated from proto/nexus/core/metadata.proto - DO NOT EDIT.

This module is generated by: python scripts/gen_metadata.py
SSOT: proto/nexus/core/metadata.proto

Compact file metadata for memory-efficient storage at scale.

String fields are stored as integer IDs (4 bytes each) instead of
full string objects. This reduces memory from ~200-300 bytes to
~64-100 bytes per file at 1M+ file scale.

Timestamps are stored as ISO 8601 strings to preserve precision
and timezone information across serialization boundaries.
"""

from __future__ import annotations

from dataclasses import dataclass
from datetime import datetime
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from nexus.contracts.metadata import FileMetadata

# --- String interning ---
# Single global pool: string -> int ID, and reverse lookup.
# All string fields share one pool for simplicity.

_STRING_POOL: dict[str, int] = {}
_STRING_POOL_REVERSE: dict[int, str] = {}
_NEXT_ID: int = 0


def _intern(s: str | None) -> int:
    """Intern a string and return its ID. Returns -1 for None."""
    global _NEXT_ID
    if s is None:
        return -1
    if s not in _STRING_POOL:
        _STRING_POOL[s] = _NEXT_ID
        _STRING_POOL_REVERSE[_NEXT_ID] = s
        _NEXT_ID += 1
    return _STRING_POOL[s]


def _resolve(id: int) -> str | None:
    """Resolve a string ID back to its value. Returns None for -1."""
    if id == -1:
        return None
    return _STRING_POOL_REVERSE.get(id)


def _resolve_required(id: int) -> str:
    """Resolve a required string field. Raises if not found."""
    result = _STRING_POOL_REVERSE.get(id)
    if result is None:
        raise ValueError(f"Interned string ID {id} not found in pool")
    return result


@dataclass(frozen=True)
class CompactFileMetadata:
    """Memory-optimized FileMetadata using string interning.

    Generated from: proto/nexus/core/metadata.proto

    String fields are stored as integer IDs (4 bytes each) instead of
    full string objects. This reduces per-instance memory significantly.
    """

    path_id: int
    size: int
    content_id_intern: int
    mime_type_id: int
    created_at: str | None
    modified_at: str | None
    version: int
    zone_id_intern: int
    owner_id_intern: int
    entry_type: int
    target_zone_id_intern: int
    last_writer_address_id: int
    link_target_id: int
    gen: int

    @classmethod
    def from_file_metadata(cls, m: FileMetadata) -> CompactFileMetadata:
        """Create CompactFileMetadata from FileMetadata."""
        return cls(
            path_id=_intern(m.path),
            size=m.size,
            content_id_intern=_intern(m.content_id),
            mime_type_id=_intern(m.mime_type),
            created_at=m.created_at.isoformat() if m.created_at else None,
            modified_at=m.modified_at.isoformat() if m.modified_at else None,
            version=m.version,
            zone_id_intern=_intern(m.zone_id),
            owner_id_intern=_intern(m.owner_id),
            entry_type=m.entry_type,
            target_zone_id_intern=_intern(m.target_zone_id),
            last_writer_address_id=_intern(m.last_writer_address),
            link_target_id=_intern(m.link_target),
            gen=m.gen,
        )

    def to_file_metadata(self) -> FileMetadata:
        """Convert back to FileMetadata."""
        from nexus.contracts.metadata import FileMetadata

        return FileMetadata(
            path=_resolve_required(self.path_id),
            size=self.size,
            content_id=_resolve(self.content_id_intern),
            mime_type=_resolve(self.mime_type_id),
            created_at=datetime.fromisoformat(self.created_at) if self.created_at else None,
            modified_at=datetime.fromisoformat(self.modified_at) if self.modified_at else None,
            version=self.version,
            zone_id=_resolve(self.zone_id_intern),
            owner_id=_resolve(self.owner_id_intern),
            entry_type=self.entry_type,
            target_zone_id=_resolve(self.target_zone_id_intern),
            last_writer_address=_resolve(self.last_writer_address_id),
            link_target=_resolve(self.link_target_id),
            gen=self.gen,
        )


def get_intern_pool_stats() -> dict[str, int]:
    """Get string interning pool statistics."""
    return {
        "count": len(_STRING_POOL),
        "memory_estimate": sum(len(s) for s in _STRING_POOL) + len(_STRING_POOL) * 100,
    }


def clear_intern_pool() -> None:
    """Clear the intern pool. Use only for testing."""
    global _NEXT_ID
    _STRING_POOL.clear()
    _STRING_POOL_REVERSE.clear()
    _NEXT_ID = 0
