#!/bin/bash

# Ginxsom Admin API Test Script
# Tests admin API endpoints using nak (for Nostr events) and curl
#
# Prerequisites:
# - nak: https://github.com/fiatjaf/nak
# - curl
# - jq (for JSON parsing)
# - Admin pubkey configured in ginxsom server_config

set -e

# Configuration
GINXSOM_URL="http://localhost:9001"

# Test admin keys (for development/testing only - DO NOT USE IN PRODUCTION)
TEST_ADMIN_PRIVKEY="993bf9c54fc00bd32a5a1ce64b6d384a5fce109df1e9aee9be1052c1e5cd8120"
TEST_ADMIN_PUBKEY="2ef05348f28d24e0f0ed0751278442c27b62c823c37af8d8d89d8592c6ee84e7"

ADMIN_PRIVKEY="${ADMIN_PRIVKEY:-${TEST_ADMIN_PRIVKEY}}"
ADMIN_PUBKEY=""

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Helper functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

check_dependencies() {
    log_info "Checking dependencies..."

    for cmd in nak curl jq; do
        if ! command -v $cmd &> /dev/null; then
            log_error "$cmd is not installed"
            case $cmd in
                nak)
                    echo "Install from: https://github.com/fiatjaf/nak"
                    ;;
                jq)
                    echo "Install jq for JSON processing"
                    ;;
                curl)
                    echo "curl should be available in most systems"
                    ;;
            esac
            exit 1
        fi
    done

    log_success "All dependencies found"
}

generate_admin_keys() {
    if [[ -z "$ADMIN_PRIVKEY" ]]; then
        log_info "Generating new admin key pair..."
        ADMIN_PRIVKEY=$(nak key generate)
        log_warning "Generated new admin private key: $ADMIN_PRIVKEY"
        log_warning "Save this key for future use: export ADMIN_PRIVKEY='$ADMIN_PRIVKEY'"
    fi

    ADMIN_PUBKEY=$(echo "$ADMIN_PRIVKEY" | nak key public)
    log_info "Admin public key: $ADMIN_PUBKEY"
}

create_admin_event() {
    local method="$1"
    local endpoint="$2"
    local content="admin_request"
    local expiration=$(($(date +%s) + 3600))  # 1 hour from now

    # Create Nostr event with nak - use kind 33335 for admin/configuration events
    local event=$(nak event -k 33335 -c "$content" \
        --tag method="$method" \
        --tag endpoint="$endpoint" \
        --tag expiration="$expiration" \
        --sec "$ADMIN_PRIVKEY")

    echo "$event"
}

send_admin_request() {
    local method="$1"
    local endpoint="$2"
    local data="$3"

    log_info "Testing $method $endpoint"

    # Create authenticated Nostr event with method and endpoint
    local event=$(create_admin_event "$method" "$endpoint")
    local auth_header="Nostr $(echo "$event" | base64 -w 0)"

    # Send request with curl
    local curl_args=(-s -w "%{http_code}" -H "Authorization: $auth_header")

    if [[ "$method" == "PUT" && -n "$data" ]]; then
        curl_args+=(-H "Content-Type: application/json" -d "$data")
    fi

    local response=$(curl "${curl_args[@]}" -X "$method" "$GINXSOM_URL$endpoint")
    local http_code="${response: -3}"
    local body="${response%???}"

    if [[ "$http_code" =~ ^2 ]]; then
        log_success "$method $endpoint - HTTP $http_code"
        if [[ -n "$body" ]]; then
            echo "$body" | jq . 2>/dev/null || echo "$body"
        fi
    else
        log_error "$method $endpoint - HTTP $http_code"
        echo "$body" | jq . 2>/dev/null || echo "$body"
    fi

    return $([[ "$http_code" =~ ^2 ]])
}

test_health_endpoint() {
    log_info "=== Testing Health Endpoint (no auth required) ==="

    local response=$(curl -s -w "%{http_code}" "$GINXSOM_URL/api/health")
    local http_code="${response: -3}"
    local body="${response%???}"

    if [[ "$http_code" =~ ^2 ]]; then
        log_success "GET /api/health - HTTP $http_code"
        echo "$body" | jq .
    else
        log_error "GET /api/health - HTTP $http_code"
        echo "$body"
    fi
}

test_stats_endpoint() {
    log_info "=== Testing Statistics Endpoint ==="
    send_admin_request "GET" "/api/stats"
}

test_config_endpoints() {
    log_info "=== Testing Configuration Endpoints ==="

    # Get current config
    send_admin_request "GET" "/api/config"

    # Update config
    local config_update='{
        "max_file_size": "209715200",
        "require_auth": "true",
        "nip94_enabled": "true"
    }'

    send_admin_request "PUT" "/api/config" "$config_update"

    # Get config again to verify
    send_admin_request "GET" "/api/config"
}

test_files_endpoint() {
    log_info "=== Testing Files Endpoint ==="
    send_admin_request "GET" "/api/files?limit=10&offset=0"
}

configure_server_admin() {
    log_warning "=== Server Configuration Required ==="
    log_warning "To use this admin interface, add the following to your ginxsom database:"
    log_warning ""
    log_warning "sqlite3 db/ginxsom.db << EOF"
    log_warning "INSERT OR REPLACE INTO server_config (key, value, description) VALUES"
    log_warning "    ('admin_pubkey', '$ADMIN_PUBKEY', 'Nostr public key authorized for admin operations'),"
    log_warning "    ('admin_enabled', 'true', 'Enable admin interface');"
    log_warning "EOF"
    log_warning ""
    log_warning "Then restart ginxsom server."

    echo ""
    log_warning "Or use the Nak utility to interact with the API:"
    echo ""
    log_warning "  # Create an event"
    echo "  EVENT=\$(nak event -k 24242 -c 'admin_request' --tag t='GET' --tag expiration=\$(date -d '+1 hour' +%s) --sec '$ADMIN_PRIVKEY')"
    echo ""
    log_warning "  # Send authenticated request"
    echo "  curl -H \"Authorization: Nostr \$(echo \"\$EVENT\" | base64 -w 0)\" http://localhost:9001/api/stats"
    echo ""
}

main() {
    echo "=== Ginxsom Admin API Test Suite ==="
    echo ""

    check_dependencies
    generate_admin_keys

    # Setup admin configuration automatically
    echo ""
    log_info "Setting up admin configuration..."
    ./tests/init_admin.sh
    echo ""

    # Test endpoints
    test_health_endpoint
    echo ""

    test_stats_endpoint
    echo ""

    test_config_endpoints
    echo ""

    test_files_endpoint
    echo ""

    log_success "Admin API testing complete!"
    log_info "Admin pubkey for server config: $ADMIN_PUBKEY"
}

# Allow sourcing for individual function testing
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi