"""Project capability contract reconciliation primitives.

Core owns the decision and ledger; the worker applies the resulting policy
snapshot to Cloud. Generated source is never silently rewritten by this path.
"""

from __future__ import annotations

import hashlib
import json
from typing import Any


def build_contract_snapshot(rows: list[dict[str, Any]]) -> dict[str, Any]:
    packs = [
        {
            "slug": str(row["slug"]),
            "installed_version": str(row.get("installed_version") or ""),
            "current_version": str(row.get("current_version") or ""),
            "status": str(row.get("status") or ""),
        }
        for row in rows
    ]
    packs.sort(key=lambda item: item["slug"])
    return {"schema_version": 1, "packs": packs}


def contract_fingerprint(snapshot: dict[str, Any]) -> str:
    encoded = json.dumps(snapshot, sort_keys=True, separators=(",", ":")).encode()
    return hashlib.sha256(encoded).hexdigest()


def reconciliation_status(snapshot: dict[str, Any]) -> tuple[str, str | None]:
    stale = [
        item for item in snapshot.get("packs", [])
        if item.get("installed_version") != item.get("current_version")
    ]
    if stale:
        return "upgrade_available", "regenerate_or_reinstall_pack"
    return "applied", None
