#!/bin/bash

# Common utilities for CodeVibe hooks
# This file provides shared functions for all hook scripts

# ─── Reviewer-subprocess short-circuit ───────────────────────────────
#
# When $QUORUM_REVIEWER_SUBPROCESS is set, the current `claude`
# invocation is a reviewer subprocess spawned by Quorum 2.0's
# `ClaudeReviewerProvider` (codevibe-core-rs/crates/codevibe-reviewer/
# src/providers/claude.rs). Reviewer subprocesses use
# `claude --print --allowed-tools Read,Grep,Glob` and have their own
# ephemeral session id that MUST NOT interact with the user's
# primary Claude Code session state.
#
# Without this guard, every reviewer spawn would fire SessionStart →
# the daemon-spawn path in session-start.sh launches a second daemon
# (or, more dangerously, finds a port-file collision and POSTs to
# the user's primary daemon, polluting its in-memory session state).
# The same bug class was empirically observed 2026-04-21 with the
# Gemini provider and the same plugin pattern; this guard prevents
# the same bug from biting Claude users.
#
# `--bare` would solve this CLI-side, but it disables OAuth/keychain
# reads — most CodeVibe users sign into Claude Code via Anthropic
# OAuth (Pro/Max), so `--bare` would refuse to authenticate. The env
# var is the OAuth-compatible defense.
#
# Because `common.sh` is sourced by every hook script (session-start,
# session-end, user-prompt, post-tool-use, stop, permission-request,
# notification), `exit 0` here propagates to the hook script —
# Claude Code sees a clean hook success and continues normally.
# Zero-impact for normal user sessions (the env var is never set in
# the 1.0 code path).
#
# This change belongs on 1.0 main because it protects the 1.0
# primary-session-isolation invariant. The env var name is the same
# `QUORUM_*` scope used by the Gemini and Codex plugins' matching
# guards.
if [ -n "$QUORUM_REVIEWER_SUBPROCESS" ]; then
    exit 0
fi

# Configuration
# Use TMPDIR if set (macOS sets this to user-specific temp), otherwise /tmp
CODEVIBE_TMPDIR="${TMPDIR:-/tmp}"
LOG_FILE="${LOG_FILE:-${CODEVIBE_TMPDIR}/codevibe-claude-hooks.log}"
DEFAULT_PORT="${DEFAULT_PORT:-3456}"

# Log a message with timestamp
log() {
  local level="$1"
  shift
  local message="$*"
  echo "[$(date -u +"%Y-%m-%dT%H:%M:%SZ")] [$level] $message" >> "$LOG_FILE"
}

# Get the MCP server URL for a given session
# Uses session-specific port file if available, otherwise falls back to default
get_mcp_server_url() {
  local session_id="$1"
  local port="$DEFAULT_PORT"

  # Try to read session-specific port file
  if [ -n "$session_id" ]; then
    local port_file="${CODEVIBE_TMPDIR}/codevibe-claude-${session_id}.port"
    if [ -f "$port_file" ]; then
      port=$(cat "$port_file")
      log "DEBUG" "Using port from file $port_file: $port"
    else
      log "DEBUG" "Port file not found: $port_file, using default port $port"
    fi
  fi

  echo "http://localhost:${port}"
}

# Read JSON input from stdin
read_json_input() {
  # Read all input from stdin
  cat
}

# Send event to MCP server via HTTP POST
# Usage: send_to_mcp <endpoint> <json_data> [session_id]
send_to_mcp() {
  local endpoint="$1"
  local json_data="$2"
  local session_id="$3"

  # Get the MCP server URL for this session
  local mcp_url=$(get_mcp_server_url "$session_id")

  log "INFO" "Sending to MCP server: POST $mcp_url/$endpoint"
  log "DEBUG" "Payload: $json_data"

  # Send HTTP POST request to MCP server
  local response
  local http_code

  response=$(curl -s -w "\n%{http_code}" \
    -X POST \
    -H "Content-Type: application/json" \
    -d "$json_data" \
    "$mcp_url/$endpoint" 2>&1)

  http_code=$(echo "$response" | tail -n 1)
  # Use sed instead of head -n -1 for macOS compatibility
  local body=$(echo "$response" | sed '$d')

  if [ "$http_code" = "200" ]; then
    log "INFO" "Successfully sent to MCP server (HTTP $http_code)"
    log "DEBUG" "Response: $body"
    return 0
  else
    log "ERROR" "Failed to send to MCP server (HTTP $http_code)"
    log "ERROR" "Response: $body"
    return 1
  fi
}

# Extract field from JSON using grep/sed (simple alternative to jq)
# This is a basic implementation - for complex JSON, consider using jq
extract_field() {
  local json="$1"
  local field="$2"

  # Simple regex-based extraction (works for simple string values)
  echo "$json" | grep -o "\"$field\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" | sed "s/\"$field\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\"/\1/"
}

# Check if MCP server is running
# Usage: check_mcp_server [session_id]
check_mcp_server() {
  local session_id="$1"
  local mcp_url=$(get_mcp_server_url "$session_id")

  log "DEBUG" "Checking if MCP server is running at $mcp_url"

  local response
  response=$(curl -s "$mcp_url/health" 2>&1)

  if [ $? -eq 0 ]; then
    log "DEBUG" "MCP server is running"
    return 0
  else
    log "WARN" "MCP server is not responding at $mcp_url"
    return 1
  fi
}

# Export variables and functions for use in other scripts
export CODEVIBE_TMPDIR
export -f log
export -f get_mcp_server_url
export -f read_json_input
export -f send_to_mcp
export -f extract_field
export -f check_mcp_server
