#!/usr/bin/env python3
"""Illustrative Claude Code PreToolUse path policy, not a filesystem sandbox.

Operator sets AGENT_WORKSPACE to an absolute, existing project directory.
Only Edit/Write beneath its existing src directory may pass this hook.
Other tools, races after checking, and secret content need separate controls.
Exit 0 leaves the host's normal permission checks in place; it does not approve.
"""
import json
import os
from pathlib import Path
import sys


def deny(reason):
    print(f"Blocked: {reason}", file=sys.stderr)
    raise SystemExit(2)


try:
    event = json.load(sys.stdin)
    if not isinstance(event, dict) or event.get("hook_event_name") != "PreToolUse":
        deny("expected a PreToolUse event")
    if event.get("tool_name") not in ("Edit", "Write"):
        deny("this handler only supports Edit and Write")
    tool_input = event.get("tool_input")
    raw = tool_input.get("file_path") if isinstance(tool_input, dict) else None
    if not isinstance(raw, str) or not raw.strip():
        deny("missing file_path")
    root = Path(os.environ["AGENT_WORKSPACE"])
    if not root.is_absolute():
        deny("AGENT_WORKSPACE must be absolute")
    root = root.resolve(strict=True)
    allowed = (root / "src").resolve(strict=True)
    if not allowed.is_dir() or allowed == root or not allowed.is_relative_to(root):
        deny("src must be a directory inside the workspace")
    candidate = Path(raw)
    if not candidate.is_absolute():
        candidate = root / candidate
    target = candidate.resolve()
    if target == allowed or not target.is_relative_to(allowed):
        deny("writes are restricted to the src tree")
    parts = target.relative_to(allowed).parts
    if any(part.startswith(".") for part in parts):
        deny("hidden paths are excluded, including .env and .example directories")
    if target.name in ("CLAUDE.md", "AGENTS.md", "wrangler.toml", "GoogleService-Info.plist"):
        deny("instruction or configuration file")
    if target.suffix == ".xcconfig":
        deny("configuration file")
except (ValueError, TypeError, KeyError, OSError, RuntimeError):
    deny("invalid input or unresolved policy configuration")
raise SystemExit(0)
