"""
Content-addressable hashing for releaseops.

All artifacts and bundles are identified by their SHA-256 content hash,
enabling immutability verification and tamper detection.
"""

from __future__ import annotations

import hashlib
from pathlib import Path
from typing import Dict, List


def hash_content(content: str) -> str:
    """SHA-256 hash of string content, prefixed with 'sha256:'."""
    digest = hashlib.sha256(content.encode("utf-8")).hexdigest()
    return f"sha256:{digest}"


def hash_file(path: Path) -> str:
    """SHA-256 hash of a file's content."""
    content = path.read_text(encoding="utf-8")
    return hash_content(content)


def hash_bundle(artifact_hashes: List[str], model_config_hash: str | None = None) -> str:
    """
    Compute the bundle hash from all artifact content hashes.

    The bundle hash is deterministic: sort artifact hashes alphabetically,
    concatenate with the model config hash, and SHA-256 the result.
    """
    parts = sorted(artifact_hashes)
    if model_config_hash:
        parts.append(model_config_hash)
    combined = "\n".join(parts)
    return hash_content(combined)


def verify_hash(content: str, expected_hash: str) -> bool:
    """Verify that content matches its expected hash."""
    actual = hash_content(content)
    return actual == expected_hash


def hash_dict(data: dict) -> str:
    """
    Deterministic hash of a dictionary.

    Serializes keys in sorted order for reproducibility.
    Used for hashing model configs and other structured data.
    """
    import json

    canonical = json.dumps(data, sort_keys=True, separators=(",", ":"))
    return hash_content(canonical)
