#!/bin/bash

# Simple test for Kind 23458 relay-based admin commands
# Tests config_query command via Nostr relay subscription

set -e

# Configuration
TEST_KEYS_FILE=".test_keys"
RELAY_URL="wss://relay.laantungir.net"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# Load test keys
if [[ ! -f "$TEST_KEYS_FILE" ]]; then
    log_error "$TEST_KEYS_FILE not found"
    exit 1
fi

source "$TEST_KEYS_FILE"

# Check dependencies
for cmd in nak jq websocat; do
    if ! command -v $cmd &> /dev/null; then
        log_error "$cmd is not installed"
        exit 1
    fi
done

echo "=== Kind 23458 Admin Command Test ==="
echo ""
log_info "Configuration:"
log_info "  Admin Privkey: ${ADMIN_PRIVKEY:0:16}..."
log_info "  Server Pubkey: $SERVER_PUBKEY"
log_info "  Relay URL:     $RELAY_URL"
echo ""

# Test 1: Send config_query command
log_info "Test: Sending config_query command"
echo ""

# Encrypt command with NIP-44
# Command format: ["config_query"]
PLAINTEXT_COMMAND='["config_query"]'

log_info "Encrypting command with NIP-44..."
ENCRYPTED_COMMAND=$(nak encrypt --sec "$ADMIN_PRIVKEY" -p "$SERVER_PUBKEY" "$PLAINTEXT_COMMAND")

if [[ -z "$ENCRYPTED_COMMAND" ]]; then
    log_error "Failed to encrypt command"
    exit 1
fi

log_success "Command encrypted"
log_info "Encrypted content: ${ENCRYPTED_COMMAND:0:50}..."
echo ""

log_info "Creating Kind 23458 event..."
EVENT=$(nak event -k 23458 \
    -c "$ENCRYPTED_COMMAND" \
    --tag p="$SERVER_PUBKEY" \
    --sec "$ADMIN_PRIVKEY")

if [[ -z "$EVENT" ]]; then
    log_error "Failed to create event"
    exit 1
fi

log_success "Event created"
echo "$EVENT" | jq .
echo ""

# Step 1: Create pipes for bidirectional communication
log_info "Step 1: Setting up websocat connection..."
SINCE=$(date +%s)

# Create named pipes for input and output
INPUT_PIPE=$(mktemp -u)
OUTPUT_PIPE=$(mktemp -u)
mkfifo "$INPUT_PIPE"
mkfifo "$OUTPUT_PIPE"

# Start websocat in background with bidirectional communication
(websocat "$RELAY_URL" < "$INPUT_PIPE" > "$OUTPUT_PIPE" 2>/dev/null) &
WEBSOCAT_PID=$!

# Open pipes for writing and reading
exec 3>"$INPUT_PIPE"  # File descriptor 3 for writing
exec 4<"$OUTPUT_PIPE" # File descriptor 4 for reading

# Give connection time to establish
sleep 1
log_success "WebSocket connection established"
echo ""

# Step 2: Subscribe to Kind 23459 responses
log_info "Step 2: Subscribing to Kind 23459 responses..."

# Create subscription filter
SUBSCRIPTION_FILTER='["REQ","admin-response",{"kinds":[23459],"authors":["'$SERVER_PUBKEY'"],"#p":["'$ADMIN_PUBKEY'"],"since":'$SINCE'}]'

# Send subscription
echo "$SUBSCRIPTION_FILTER" >&3
sleep 1
log_success "Subscription sent"
echo ""

# Step 3: Publish the command event
log_info "Step 3: Publishing Kind 23458 command event..."

# Create EVENT message
EVENT_MSG='["EVENT",'$EVENT']'

# Send event
echo "$EVENT_MSG" >&3
sleep 1
log_success "Event published"
echo ""

# Step 4: Wait for response
log_info "Step 4: Waiting for Kind 23459 response (timeout: 15s)..."

RESPONSE_RECEIVED=0
TIMEOUT=15
START_TIME=$(date +%s)

while [[ $(($(date +%s) - START_TIME)) -lt $TIMEOUT ]]; do
    if read -t 1 -r line <&4; then
        if [[ -n "$line" ]]; then
            # Parse the relay message
            MSG_TYPE=$(echo "$line" | jq -r '.[0] // empty' 2>/dev/null)
            
            if [[ "$MSG_TYPE" == "EVENT" ]]; then
                # Extract the event (third element in array)
                EVENT_DATA=$(echo "$line" | jq '.[2]' 2>/dev/null)
                
                if [[ -n "$EVENT_DATA" ]]; then
                    log_success "Received Kind 23459 response!"
                    echo "$EVENT_DATA" | jq .
                    echo ""

                    # Extract and decrypt content
                    ENCRYPTED_CONTENT=$(echo "$EVENT_DATA" | jq -r '.content // empty')
                    SENDER_PUBKEY=$(echo "$EVENT_DATA" | jq -r '.pubkey // empty')

                    if [[ -n "$ENCRYPTED_CONTENT" ]] && [[ -n "$SENDER_PUBKEY" ]]; then
                        log_info "Encrypted response: ${ENCRYPTED_CONTENT:0:50}..."
                        log_info "Sender pubkey: $SENDER_PUBKEY"
                        log_info "Decrypting response..."

                        # Try decryption with error output and timeout
                        DECRYPT_OUTPUT=$(timeout 5s nak decrypt --sec "$ADMIN_PRIVKEY" -p "$SENDER_PUBKEY" "$ENCRYPTED_CONTENT" 2>&1)
                        DECRYPT_EXIT=$?

                        if [[ $DECRYPT_EXIT -eq 0 ]] && [[ -n "$DECRYPT_OUTPUT" ]]; then
                            log_success "Response decrypted successfully:"
                            echo "$DECRYPT_OUTPUT" | jq . 2>/dev/null || echo "$DECRYPT_OUTPUT"
                            RESPONSE_RECEIVED=1
                        else
                            log_error "Failed to decrypt response (exit code: $DECRYPT_EXIT)"
                            if [[ -n "$DECRYPT_OUTPUT" ]]; then
                                log_error "Decryption error: $DECRYPT_OUTPUT"
                            fi
                        fi
                    fi
                    break
                fi
            fi
        fi
    fi
done

# Cleanup
exec 3>&-  # Close write pipe
exec 4<&-  # Close read pipe
kill $WEBSOCAT_PID 2>/dev/null
rm -f "$INPUT_PIPE" "$OUTPUT_PIPE"

if [[ $RESPONSE_RECEIVED -eq 0 ]]; then
    log_error "No response received within timeout period"
    log_info "This could mean:"
    log_info "  1. The server didn't receive the command"
    log_info "  2. The server received but didn't process the command"
    log_info "  3. The response was sent but not received by subscription"
    exit 1
fi

echo ""
log_success "Test complete!"
echo ""
log_info "This test uses full NIP-44 encryption for both commands and responses."