# ============================================================
# src/accountable_record/stage_030_sources/load.py
# ============================================================
"""Load declared source material paths for stage 030.

WHY:
    Stage 030 validates repository source materials. For schema-valid manifests,
    source-like repository materials are declared through [provides].artifacts,
    not through a schema-forbidden [sources] section.

OBS:
    This loader is source-stage code only. It does not read contract fields and
    does not construct ContractDeclaration.
"""

from pathlib import Path

from accountable_record.stage_010_identity.manifest import load_manifest_data
from accountable_record.stage_030_sources.base.scalars import (
    required_string_list,
    required_table,
)
from accountable_record.stage_030_sources.model import SourceRecord


def load_declared_source_records(repo_root: Path) -> tuple[SourceRecord, ...]:
    """Load source-material records from manifest [provides].artifacts.

    Args:
        repo_root: Repository root containing SE_MANIFEST.toml.

    Returns:
        Declared source records.

    Raises:
        FileNotFoundError: If no manifest is present.
        ValueError: If [provides].artifacts is absent or malformed.
    """
    _manifest_filename, manifest = load_manifest_data(repo_root)

    provides = required_table(manifest, "provides", "manifest")
    artifacts = required_string_list(provides, "artifacts", "[provides]")

    return tuple(
        SourceRecord(
            source_id=_source_id_for_artifact(artifact),
            rel_path=artifact,
            role="provided-artifact",
            present=(repo_root / artifact).exists(),
        )
        for artifact in artifacts
    )


def _source_id_for_artifact(rel_path: str) -> str:
    """Return a stable source id derived from a manifest artifact path."""
    cleaned = rel_path.strip().strip("/").replace("\\", "/")
    if not cleaned:
        return "artifact.root"

    parts = [
        part.replace(".", "-").replace("_", "-") for part in cleaned.split("/") if part
    ]
    return "artifact." + ".".join(parts)
