from __future__ import annotations

from dataclasses import asdict, dataclass
from pathlib import Path
import json

from .serialization import to_jsonable


ARTIFACT_SCHEMA_VERSION = "1.0"


@dataclass(frozen=True)
class ArtifactEnvelope:
    artifact_type: str
    schema_version: str
    payload: object
    metadata: dict[str, object]


@dataclass(frozen=True)
class ArtifactManifestEntry:
    artifact_type: str
    file_name: str


@dataclass(frozen=True)
class ArtifactManifest:
    schema_version: str
    artifacts: tuple[ArtifactManifestEntry, ...]
    metadata: dict[str, object]


def make_artifact_envelope(
    artifact_type: str,
    payload: object,
    *,
    metadata: dict[str, object] | None = None,
) -> ArtifactEnvelope:
    return ArtifactEnvelope(
        artifact_type=artifact_type,
        schema_version=ARTIFACT_SCHEMA_VERSION,
        payload=to_jsonable(payload),
        metadata=dict(metadata or {}),
    )


def save_artifact_json(
    artifact_type: str,
    payload: object,
    path: str | Path,
    *,
    metadata: dict[str, object] | None = None,
) -> None:
    destination = Path(path)
    envelope = make_artifact_envelope(
        artifact_type,
        payload,
        metadata=metadata,
    )
    destination.write_text(json.dumps(asdict(envelope), indent=2), encoding="utf-8")


def save_manifest_json(manifest: ArtifactManifest, path: str | Path) -> None:
    destination = Path(path)
    destination.write_text(json.dumps(asdict(manifest), indent=2), encoding="utf-8")
