#!/usr/bin/env bash
# Integration test for review-gate Stop hook
#
# This test verifies that the Stop hook actually blocks Claude Code
# when a review is pending.
#
# Usage:
#   ./test-hook-integration.sh [--debug]
#
# Requirements:
#   - Claude CLI installed
#   - API credits available
#   - Run from the skills repo root (or set SKILLS_ROOT)

set -uo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILLS_ROOT="${SKILLS_ROOT:-$(cd "$SCRIPT_DIR/../../.." && pwd)}"
REVIEW_GATE="$SKILLS_ROOT/skills/review-gate/scripts/review-gate"
DEBUG="${1:-}"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m'

# Test state (isolated)
TEST_STATE_DIR=$(mktemp -d)
TEST_HOOKS_DIR=$(mktemp -d)
export REVIEW_STATE_DIR="$TEST_STATE_DIR"

cleanup() {
    rm -rf "$TEST_STATE_DIR" "$TEST_HOOKS_DIR"
}
trap cleanup EXIT

echo "=== Review Gate Hook Integration Test ==="
echo "Skills root: $SKILLS_ROOT"
echo "State dir: $TEST_STATE_DIR"
echo ""

# --- Setup ---
echo "## Setup"

# Create hooks.json that points to our review-gate
# Use the test state dir via environment variable
cat > "$TEST_HOOKS_DIR/hooks.json" <<EOF
{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "REVIEW_STATE_DIR=$TEST_STATE_DIR $REVIEW_GATE check",
            "timeout": 30
          }
        ]
      }
    ]
  }
}
EOF

echo "Created test hooks.json"
cat "$TEST_HOOKS_DIR/hooks.json"
echo ""

# Enable a review with a fixed session ID
# We'll set REVIEW_SESSION_ID in the hook command doesn't help because
# the hook doesn't know the session. Let's use a predictable session ID.
TEST_SESSION="integration-test-$(date +%s)"
"$REVIEW_GATE" enable "$TEST_SESSION"
echo "Enabled review for session: $TEST_SESSION"
echo ""

# Verify the state
echo "State file contents:"
cat "$TEST_STATE_DIR/$TEST_SESSION.json"
echo ""
echo ""

# --- Test 1: Hook blocks when review pending ---
echo "## Test 1: Hook script blocks when pending"

output=$("$REVIEW_GATE" check "$TEST_SESSION" 2>&1)
exit_code=$?

if [[ $exit_code -eq 2 ]]; then
    echo -e "${GREEN}PASS${NC}: Exit code is 2 (blocking)"
else
    echo -e "${RED}FAIL${NC}: Exit code is $exit_code (expected 2)"
fi

if echo "$output" | grep -q '"decision": "block"'; then
    echo -e "${GREEN}PASS${NC}: Output contains decision: block"
else
    echo -e "${RED}FAIL${NC}: Output missing decision: block"
    echo "Output was: $output"
fi

echo ""

# --- Test 2: Hook allows when approved ---
echo "## Test 2: Hook script allows when approved"

"$REVIEW_GATE" approve "$TEST_SESSION" > /dev/null
output=$("$REVIEW_GATE" check "$TEST_SESSION" 2>&1)
exit_code=$?

if [[ $exit_code -eq 0 ]]; then
    echo -e "${GREEN}PASS${NC}: Exit code is 0 (allowing)"
else
    echo -e "${RED}FAIL${NC}: Exit code is $exit_code (expected 0)"
fi

echo ""

# --- Test 3: Live Claude integration (optional) ---
echo "## Test 3: Live Claude integration"
echo ""
echo "This test runs Claude with the Stop hook and verifies blocking."
echo "It requires API credits and takes ~10-30 seconds."
echo ""

# Re-enable review for live test
"$REVIEW_GATE" enable "$TEST_SESSION" > /dev/null

# Check if we should run the live test
if [[ "${SKIP_LIVE_TEST:-}" == "1" ]]; then
    echo -e "${YELLOW}SKIP${NC}: SKIP_LIVE_TEST=1 set, skipping live test"
    exit 0
fi

echo "Running: claude -p 'Say hello' with Stop hook..."
echo ""

# Build the claude command
# We need to inject our hooks somehow. Options:
# 1. Use --mcp-config (doesn't help for hooks)
# 2. Run from a directory with .claude/hooks.json
# 3. Use debug mode to see what happens

# Create a temp project dir with our hooks
TEST_PROJECT=$(mktemp -d)
mkdir -p "$TEST_PROJECT/.claude"
cp "$TEST_HOOKS_DIR/hooks.json" "$TEST_PROJECT/.claude/hooks.json"

# Also need a way to pass REVIEW_STATE_DIR to the hook
# Rewrite hooks.json with absolute paths and env vars baked in
cat > "$TEST_PROJECT/.claude/hooks.json" <<EOF
{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "REVIEW_STATE_DIR=$TEST_STATE_DIR REVIEW_SESSION_ID=$TEST_SESSION $REVIEW_GATE check",
            "timeout": 30
          }
        ]
      }
    ]
  }
}
EOF

echo "Test project: $TEST_PROJECT"
echo "Hooks config:"
cat "$TEST_PROJECT/.claude/hooks.json"
echo ""

# Run claude from the test project directory
cd "$TEST_PROJECT"

if [[ "$DEBUG" == "--debug" ]]; then
    debug_flag="--debug hooks"
else
    debug_flag=""
fi

# Run with timeout to avoid hanging
echo "Executing claude..."
set +e
output=$(timeout 60 claude -p "Say 'hello' and nothing else" $debug_flag 2>&1)
exit_code=$?
set -e

echo "Exit code: $exit_code"
echo "Output:"
echo "$output"
echo ""

# Cleanup test project
rm -rf "$TEST_PROJECT"

# Analyze results
echo "## Analysis"

if echo "$output" | grep -qi "block"; then
    echo -e "${GREEN}PASS${NC}: Output contains 'block' - hook appears to have fired"
elif echo "$output" | grep -qi "review pending"; then
    echo -e "${GREEN}PASS${NC}: Output contains 'review pending' - hook fired"
elif echo "$output" | grep -qi "credit"; then
    echo -e "${YELLOW}SKIP${NC}: API credit issue - cannot complete live test"
elif [[ $exit_code -eq 124 ]]; then
    echo -e "${YELLOW}SKIP${NC}: Timeout - Claude may be blocked in a loop (which could mean hook is working)"
else
    echo -e "${YELLOW}INCONCLUSIVE${NC}: Could not determine if hook fired"
    echo "Check output above for clues"
fi

echo ""
echo "=== Test Complete ==="
echo ""
echo "To re-run live test when credits available:"
echo "  $0"
echo ""
echo "To skip live test:"
echo "  SKIP_LIVE_TEST=1 $0"
