#!/usr/bin/env bash
#
# StemeDB Validation Script
#
# Validates that StemeDB works end-to-end:
#   1. Builds the API server
#   2. Starts the server in the background
#   3. Waits for health check
#   4. Creates an assertion via curl
#   5. Queries it back
#   6. Shuts down the server
#
# Usage:
#   ./scripts/validate.sh           # Run validation
#   ./scripts/validate.sh --no-build  # Skip cargo build (faster)
#
# Exit codes:
#   0 - All checks passed
#   1 - Validation failed
#

set -euo pipefail

# Configuration
readonly API_HOST="${STEMEDB_BIND_ADDR:-127.0.0.1:18180}"
readonly API_URL="http://${API_HOST}"
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
readonly DATA_DIR="${PROJECT_DIR}/tmp/validate-$$"
readonly PID_FILE="${DATA_DIR}/server.pid"
readonly LOG_FILE="${DATA_DIR}/server.log"

# Colors (if terminal supports it)
if [[ -t 1 ]]; then
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[0;33m'
    BLUE='\033[0;34m'
    NC='\033[0m' # No Color
else
    RED=''
    GREEN=''
    YELLOW=''
    BLUE=''
    NC=''
fi

# Logging helpers
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
success() { echo -e "${GREEN}[PASS]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
fail() { echo -e "${RED}[FAIL]${NC} $*"; exit 1; }

# Cleanup on exit
cleanup() {
    if [[ -f "$PID_FILE" ]]; then
        local pid
        pid=$(cat "$PID_FILE")
        if kill -0 "$pid" 2>/dev/null; then
            info "Stopping server (PID $pid)..."
            kill "$pid" 2>/dev/null || true
            wait "$pid" 2>/dev/null || true
        fi
    fi
    if [[ -d "$DATA_DIR" ]]; then
        rm -rf "$DATA_DIR"
    fi
}
trap cleanup EXIT

# Parse arguments
SKIP_BUILD=false
for arg in "$@"; do
    case $arg in
        --no-build)
            SKIP_BUILD=true
            ;;
        --help|-h)
            echo "Usage: $0 [--no-build]"
            echo ""
            echo "Validates StemeDB end-to-end (build, start, assert, query, shutdown)."
            echo ""
            echo "Options:"
            echo "  --no-build    Skip cargo build (use existing binary)"
            echo "  --help        Show this help message"
            exit 0
            ;;
    esac
done

# Main validation
main() {
    echo ""
    echo "=========================================="
    echo "  StemeDB Validation"
    echo "=========================================="
    echo ""

    # Create temp data directory
    mkdir -p "$DATA_DIR"

    # Step 1: Build
    if [[ "$SKIP_BUILD" == "false" ]]; then
        info "Building stemedb-api..."
        cd "$PROJECT_DIR"
        if ! cargo build --package stemedb-api --quiet 2>&1; then
            fail "Build failed"
        fi
        success "Build complete"
    else
        info "Skipping build (--no-build)"
    fi

    # Step 2: Start server
    info "Starting API server..."
    cd "$PROJECT_DIR"
    STEMEDB_WAL_DIR="$DATA_DIR/wal" \
    STEMEDB_DB_DIR="$DATA_DIR/db" \
    STEMEDB_BIND_ADDR="$API_HOST" \
    cargo run --package stemedb-api --quiet > "$LOG_FILE" 2>&1 &
    echo $! > "$PID_FILE"

    # Step 3: Wait for health
    info "Waiting for server to be ready..."
    local attempts=0
    local max_attempts=30
    while [[ $attempts -lt $max_attempts ]]; do
        if curl -s "${API_URL}/v1/health" > /dev/null 2>&1; then
            break
        fi
        sleep 0.5
        ((attempts++))
    done

    if [[ $attempts -eq $max_attempts ]]; then
        echo ""
        echo "Server log:"
        cat "$LOG_FILE" || true
        fail "Server failed to start within 15 seconds"
    fi
    success "Server is healthy"

    # Step 4: Health check details
    info "Checking health endpoint..."
    local health_response
    health_response=$(curl -s "${API_URL}/v1/health")
    echo "  Response: $health_response"

    if ! echo "$health_response" | grep -q '"status":"healthy"'; then
        fail "Health check failed"
    fi
    success "Health check passed"

    # Step 5: Create a properly signed assertion
    info "Creating assertion (with valid Ed25519 signature)..."

    # Generate a properly signed assertion using the helper binary
    # This creates a fresh keypair and signs "{subject}:{predicate}"
    local assertion_json
    assertion_json=$(cargo run --package stemedb-api --example gen_test_assertion --quiet 2>/dev/null)

    if [[ -z "$assertion_json" ]]; then
        fail "Failed to generate signed assertion"
    fi

    local assert_response
    assert_response=$(curl -s -X POST "${API_URL}/v1/assert" \
        -H "Content-Type: application/json" \
        -d "$assertion_json")

    echo "  Response: $assert_response"

    if ! echo "$assert_response" | grep -q '"status":"created"'; then
        fail "Assertion creation failed"
    fi

    local assertion_hash
    assertion_hash=$(echo "$assert_response" | grep -o '"hash":"[^"]*"' | cut -d'"' -f4)
    success "Assertion created: ${assertion_hash:0:16}..."

    # Step 6: Query the assertion back (with retry for ingestion)
    info "Querying assertion..."

    # Retry loop - ingestion worker needs time to process WAL
    local query_attempts=0
    local query_max_attempts=10
    local query_response=""

    while [[ $query_attempts -lt $query_max_attempts ]]; do
        query_response=$(curl -s "${API_URL}/v1/query?subject=StemeDB_Validation&predicate=test_status")
        local count
        count=$(echo "$query_response" | grep -o '"total_count":[0-9]*' | cut -d':' -f2)

        if [[ "$count" -gt 0 ]] 2>/dev/null; then
            break
        fi

        sleep 0.5
        ((query_attempts++))
    done

    echo "  Total count: $(echo "$query_response" | grep -o '"total_count":[0-9]*' | cut -d':' -f2)"
    echo "  Ingestion took ~$((query_attempts * 500))ms"

    if ! echo "$query_response" | grep -q '"StemeDB_Validation"'; then
        echo "  Full response: $query_response"
        fail "Query did not return expected subject (tried ${query_attempts} times)"
    fi

    if ! echo "$query_response" | grep -q '"working"'; then
        fail "Query did not return expected value"
    fi
    success "Query returned correct data"

    # Step 7: Test query with lens
    info "Testing lens-based query..."

    local lens_response
    lens_response=$(curl -s "${API_URL}/v1/query?subject=StemeDB_Validation&predicate=test_status&lens=Recency")

    if ! echo "$lens_response" | grep -q '"working"'; then
        fail "Lens query failed"
    fi
    success "Lens query (Recency) works"

    # Final summary
    echo ""
    echo "=========================================="
    echo -e "  ${GREEN}All validation checks passed!${NC}"
    echo "=========================================="
    echo ""
    echo "StemeDB is working correctly. You can now:"
    echo "  1. Start the server:  cargo run --package stemedb-api"
    echo "  2. View API docs:     http://localhost:18180/swagger-ui"
    echo "  3. Use the Go SDK:    cd sdk/go/examples/basic && go run main.go"
    echo ""
}

main "$@"
