#!/usr/bin/env bash
# PreToolUse hook: Evaluate tool calls against cached policy rules.
#
# Reads ~/.clew/policy-cache.json (written by session-start.sh).
# Checks Write/Edit paths against protected_write/unguarded_path rules.
# Checks Bash commands and Write/Edit content against banned_import rules.
#
# Exit codes: 0 = allow (or deny via JSON), 1 = error (fail-open)
set -uo pipefail

CACHE_FILE="$HOME/.clew/policy-cache.json"

# Read hook input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')

# Fail open if no cache
if [ ! -f "$CACHE_FILE" ]; then
  exit 0
fi

POLICIES=$(cat "$CACHE_FILE" 2>/dev/null)
if [ -z "$POLICIES" ] || [ "$POLICIES" = "[]" ]; then
  exit 0
fi

# Extract tool-specific fields
case "$TOOL_NAME" in
  Write|Edit)
    FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
    CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // .tool_input.new_string // empty')
    ;;
  Bash)
    FILE_PATH=""
    CONTENT=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
    ;;
  *)
    # No policy checks for other tools
    exit 0
    ;;
esac

# Check protected_write and unguarded_path rules against file paths
if [ -n "$FILE_PATH" ]; then
  VIOLATION=$(echo "$POLICIES" | jq -r --arg path "$FILE_PATH" '
    .[] | select(.type == "protected_write" or .type == "unguarded_path") |
    select(.severity == "block") |
    .pattern as $pat |
    select(
      if ($pat | contains("*") | not) then ($path == $pat)
      elif ($pat | endswith("*")) then ($path | startswith($pat | rtrimstr("*")))
      elif ($pat | startswith("*")) then ($path | endswith($pat | ltrimstr("*")))
      else ($path | contains($pat | split("*")[0]))
      end
    ) |
    "\(.id)|\(.message)"
  ' | head -1)

  if [ -n "$VIOLATION" ]; then
    RULE_ID=$(echo "$VIOLATION" | cut -d'|' -f1)
    MESSAGE=$(echo "$VIOLATION" | cut -d'|' -f2-)
    printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Policy violation [%s]: %s"}}' \
      "$RULE_ID" "$MESSAGE"
    exit 0
  fi
fi

# Check banned_import rules against content
if [ -n "$CONTENT" ]; then
  VIOLATION=$(echo "$POLICIES" | jq -r --arg content "$CONTENT" '
    .[] | select(.type == "banned_import") |
    select(.severity == "block") |
    .pattern as $pat | select($content | test($pat)) |
    "\(.id)|\(.message)"
  ' 2>/dev/null | head -1)

  if [ -n "$VIOLATION" ]; then
    RULE_ID=$(echo "$VIOLATION" | cut -d'|' -f1)
    MESSAGE=$(echo "$VIOLATION" | cut -d'|' -f2-)
    printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Policy violation [%s]: %s"}}' \
      "$RULE_ID" "$MESSAGE"
    exit 0
  fi
fi

# No violations — allow
exit 0
