#!/usr/bin/env python3
"""Executable contract fixture for SAC's external policy adapter.

This is intentionally not a policy implementation.  It exercises the real
process/JSON/exit-code boundary while test-selected modes emulate outcomes.
"""

from __future__ import annotations

import hashlib
import json
import os
import subprocess
import sys
from pathlib import Path

POLICY_SHA = "1" * 64
PROJECTION_SHA = "2" * 64


def emit(payload: object, code: int = 0) -> None:
    print(json.dumps(payload, sort_keys=True, separators=(",", ":")))
    raise SystemExit(code)


mode = os.environ.get("SCITEX_POLICY_FIXTURE_MODE", "allow")
if mode == "invalid-json":
    print("not-json")
    raise SystemExit(0)

operation = sys.argv[1] if len(sys.argv) > 1 else ""
if operation == "check-projections":
    if mode == "stale":
        emit(
            {
                "allowed": False,
                "decision": "stale",
                "policy_sha256": POLICY_SHA,
                "stale": ["AGENTS"],
            },
            3,
        )
    emit(
        {
            "allowed": True,
            "decision": "current",
            "policy_sha256": POLICY_SHA,
            "projection_sha256": PROJECTION_SHA,
        }
    )

if operation == "check-shell":
    emit(
        {
            "allowed": True,
            "decision": "allow",
            "policy_sha256": POLICY_SHA,
            "projection_sha256": PROJECTION_SHA,
        }
    )

if operation == "check-owned-restore":
    # Contract-only receipt producer. Neutral policy's independent real-Git
    # suite tests authorization; this fixture exercises SAC receipt mechanics.
    repo = Path(sys.argv[sys.argv.index("--repo") + 1]).resolve()
    owner_file = Path(sys.argv[sys.argv.index("--owner-file") + 1])
    raw = owner_file.read_bytes()
    owner = json.loads(raw)
    target, branch = owner["worktree"], owner["branch"]
    if mode == "deny" or Path(target).exists():
        emit({"allowed": False, "reason": "fixture denied owned restore"}, 2)

    def read_git(*args):
        return subprocess.run(
            ["git", "-C", str(repo), *args], capture_output=True, text=True, check=True
        ).stdout.strip()

    status_argv = [
        "status",
        "--porcelain=v1",
        "--untracked-files=all",
        "--",
        ".",
        ":(exclude).worktrees",
    ]
    emit(
        {
            "allowed": True,
            "decision": "allow",
            "operation": "restore-owned-worktree",
            "policy_id": "scitex.worktree.fixture",
            "schema_version": 1,
            "policy_sha256": POLICY_SHA,
            "projection_sha256": PROJECTION_SHA,
            "repo_root": str(repo),
            "git_common_dir": str(repo / ".git"),
            "branch": read_git("branch", "--show-current"),
            "surface": "authority",
            "agent": owner["agent"],
            "owner_file": str(owner_file),
            "owner_sha256": hashlib.sha256(raw).hexdigest(),
            "worktree": target,
            "restore_branch": branch,
            "expected_tip": read_git("rev-parse", branch),
            "primary_head": read_git("rev-parse", "HEAD"),
            "primary_status_argv": status_argv,
            "primary_status_sha256": hashlib.sha256(
                read_git(*status_argv).encode()
            ).hexdigest(),
            "worktree_registry_sha256": hashlib.sha256(
                read_git("worktree", "list", "--porcelain").encode()
            ).hexdigest(),
            "command": ["git", "-C", str(repo), "worktree", "add", target, branch],
        }
    )

if operation not in {"inspect", "assert-context"}:
    emit({"allowed": False, "decision": "error", "error": "bad operation"}, 3)

repo = Path(sys.argv[sys.argv.index("--repo") + 1]).resolve()


def git(*args: str) -> str:
    return subprocess.run(
        ["git", "-C", str(repo), *args],
        capture_output=True,
        text=True,
        check=True,
    ).stdout.strip()


root = Path(git("rev-parse", "--show-toplevel")).resolve()
git_dir_raw = Path(git("rev-parse", "--git-dir"))
common_raw = Path(git("rev-parse", "--git-common-dir"))
git_dir = (
    (repo / git_dir_raw).resolve() if not git_dir_raw.is_absolute() else git_dir_raw
)
common = (repo / common_raw).resolve() if not common_raw.is_absolute() else common_raw
surface = "authority" if git_dir == common else "linked-worktree"
intent = sys.argv[sys.argv.index("--intent") + 1] if "--intent" in sys.argv else ""
if mode == "deny" or (
    operation == "assert-context" and surface == "authority" and intent != "read"
):
    emit(
        {
            "allowed": False,
            "decision": "deny",
            "reason": "fixture denied authority checkout",
        },
        2,
    )
projection_sha = "3" * 64 if mode == "hash-drift" else PROJECTION_SHA
emit(
    {
        "allowed": True,
        "branch": git("rev-parse", "--abbrev-ref", "HEAD"),
        "decision": "allow",
        "policy_id": "scitex.worktree.fixture",
        "policy_sha256": POLICY_SHA,
        "projection_sha256": projection_sha,
        "repo_root": str(root),
        "git_common_dir": str(common),
        "schema_version": 1,
        "surface": surface,
    }
)
