# #region ArtifactCatalogLoader [C:5] [TYPE Module] [SEMANTICS pydantic, clean-release, artifact, catalog, manifest]
# @BRIEF Load bootstrap artifact catalogs for clean release real-mode flows.
# @LAYER Domain
# @RELATION DEPENDS_ON -> [CleanReleaseModels]
# @INVARIANT  Artifact catalog must produce deterministic CandidateArtifact entries with required identity and checksum fields.
# @SIDE_EFFECT  Reads JSON file from filesystem
# @DATA_CONTRACT  FilePath -> CandidateArtifact[]

from __future__ import annotations

import json
from pathlib import Path

from ...models.clean_release import CandidateArtifact


# #region load_bootstrap_artifacts [TYPE Function]
# @BRIEF Parse artifact catalog JSON into CandidateArtifact models for TUI/bootstrap flows.
# @PRE  path points to readable JSON file; payload is list[artifact] or {"artifacts": list[artifact]}.
# @POST  Returns non-mutated CandidateArtifact models with required fields populated.
def load_bootstrap_artifacts(path: str, candidate_id: str) -> list[CandidateArtifact]:
    if not path or not path.strip():
        return []
    if not candidate_id or not candidate_id.strip():
        raise ValueError("candidate_id must be non-empty for artifact catalog import")

    catalog_path = Path(path)
    payload = json.loads(catalog_path.read_text(encoding="utf-8"))
    raw_artifacts = payload.get("artifacts") if isinstance(payload, dict) else payload
    if not isinstance(raw_artifacts, list):
        raise ValueError(
            "artifact catalog must be a list or an object with 'artifacts' list"
        )

    artifacts: list[CandidateArtifact] = []
    for index, raw_artifact in enumerate(raw_artifacts, start=1):
        if not isinstance(raw_artifact, dict):
            raise ValueError(f"artifact #{index} must be an object")

        artifact_id = str(raw_artifact.get("id", "")).strip()
        artifact_path = str(raw_artifact.get("path", "")).strip()
        artifact_sha256 = str(raw_artifact.get("sha256", "")).strip()
        artifact_size = raw_artifact.get("size")
        if not artifact_id:
            raise ValueError(f"artifact #{index} missing required field 'id'")
        if not artifact_path:
            raise ValueError(f"artifact #{index} missing required field 'path'")
        if not artifact_sha256:
            raise ValueError(f"artifact #{index} missing required field 'sha256'")
        if not isinstance(artifact_size, int) or artifact_size < 0:
            raise ValueError(
                f"artifact #{index} field 'size' must be non-negative integer"
            )

        category = (
            str(
                raw_artifact.get("detected_category")
                or raw_artifact.get("category")
                or ""
            ).strip()
            or None
        )
        source_uri = str(raw_artifact.get("source_uri", "")).strip() or None
        source_host = str(raw_artifact.get("source_host", "")).strip() or None
        metadata_json = raw_artifact.get("metadata_json")
        if metadata_json is None:
            metadata_json = {
                key: value
                for key, value in raw_artifact.items()
                if key
                not in {
                    "id",
                    "path",
                    "sha256",
                    "size",
                    "category",
                    "detected_category",
                    "source_uri",
                    "source_host",
                    "metadata_json",
                }
            }
        if not isinstance(metadata_json, dict):
            raise ValueError(f"artifact #{index} field 'metadata_json' must be object")

        artifacts.append(
            CandidateArtifact(
                id=artifact_id,
                candidate_id=candidate_id,
                path=artifact_path,
                sha256=artifact_sha256,
                size=artifact_size,
                detected_category=category,
                declared_category=category,
                source_uri=source_uri,
                source_host=source_host,
                metadata_json=metadata_json,
            )
        )

    return artifacts


# #endregion load_bootstrap_artifacts

# #endregion ArtifactCatalogLoader
