#!/bin/bash

# Persistent Subscription Test Script
# Subscribes to all events in the relay and prints them as they arrive in real-time
# This tests the persistent subscription functionality of the C-Relay

set -e  # Exit on any error

# Color constants
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
BOLD='\033[1m'
RESET='\033[0m'

# Test configuration
RELAY_URL="ws://127.0.0.1:8888"
SUBSCRIPTION_ID="persistent_test_$(date +%s)"

# Print functions
print_header() {
    echo -e "${BLUE}${BOLD}=== $1 ===${RESET}"
}

print_info() {
    echo -e "${BLUE}[INFO]${RESET} $1"
}

print_success() {
    echo -e "${GREEN}✓${RESET} $1"
}

print_error() {
    echo -e "${RED}✗${RESET} $1"
}

print_warning() {
    echo -e "${YELLOW}[WARNING]${RESET} $1"
}

print_event() {
    echo -e "${GREEN}[EVENT]${RESET} $1"
}

# Cleanup function
cleanup() {
    print_info "Cleaning up..."
    if [[ -n "$WEBSOCAT_PID" ]]; then
        kill "$WEBSOCAT_PID" 2>/dev/null || true
        wait "$WEBSOCAT_PID" 2>/dev/null || true
    fi
    
    # Send CLOSE message to clean up subscription on relay
    if command -v websocat &> /dev/null; then
        echo "[\"CLOSE\",\"$SUBSCRIPTION_ID\"]" | timeout 2s websocat "$RELAY_URL" 2>/dev/null || true
    fi
    
    print_info "Cleanup complete"
    exit 0
}

# Set up signal handlers
trap cleanup SIGINT SIGTERM

# Parse events from relay responses
parse_events() {
    while IFS= read -r line; do
        # Check if this is an EVENT message
        if echo "$line" | jq -e '. | type == "array" and length >= 3 and .[0] == "EVENT"' >/dev/null 2>&1; then
            # Extract event details
            local event_id=$(echo "$line" | jq -r '.[2].id' 2>/dev/null || echo "unknown")
            local event_kind=$(echo "$line" | jq -r '.[2].kind' 2>/dev/null || echo "unknown")
            local event_content=$(echo "$line" | jq -r '.[2].content' 2>/dev/null || echo "")
            local event_pubkey=$(echo "$line" | jq -r '.[2].pubkey' 2>/dev/null || echo "unknown")
            local event_created_at=$(echo "$line" | jq -r '.[2].created_at' 2>/dev/null || echo "unknown")
            local event_tags=$(echo "$line" | jq -r '.[2].tags | length' 2>/dev/null || echo "0")
            
            # Convert timestamp to readable format
            local readable_time="unknown"
            if [[ "$event_created_at" != "unknown" && "$event_created_at" =~ ^[0-9]+$ ]]; then
                readable_time=$(date -d "@$event_created_at" "+%Y-%m-%d %H:%M:%S" 2>/dev/null || echo "$event_created_at")
            fi
            
            # Print formatted event
            print_event "Kind: $event_kind | ID: ${event_id:0:16}... | Author: ${event_pubkey:0:16}..."
            echo -e "  ${YELLOW}Time:${RESET} $readable_time | ${YELLOW}Tags:${RESET} $event_tags"
            
            # Show content (truncated if too long)
            if [[ -n "$event_content" ]]; then
                local truncated_content="${event_content:0:100}"
                if [[ ${#event_content} -gt 100 ]]; then
                    truncated_content="${truncated_content}..."
                fi
                echo -e "  ${YELLOW}Content:${RESET} $truncated_content"
            fi
            echo # Blank line for readability
            
        elif echo "$line" | jq -e '. | type == "array" and length >= 2 and .[0] == "EOSE"' >/dev/null 2>&1; then
            # End of stored events
            local sub_id=$(echo "$line" | jq -r '.[1]' 2>/dev/null)
            print_info "End of stored events for subscription: $sub_id"
            print_success "Persistent subscription is now active - waiting for new events..."
            echo
            
        elif echo "$line" | jq -e '. | type == "array" and length >= 3 and .[0] == "CLOSED"' >/dev/null 2>&1; then
            # Subscription closed
            local sub_id=$(echo "$line" | jq -r '.[1]' 2>/dev/null)
            local reason=$(echo "$line" | jq -r '.[2]' 2>/dev/null)
            print_warning "Subscription $sub_id was closed: $reason"
            
        elif echo "$line" | jq -e '. | type == "array" and length >= 4 and .[0] == "OK"' >/dev/null 2>&1; then
            # OK response to event publishing
            local event_id=$(echo "$line" | jq -r '.[1]' 2>/dev/null)
            local success=$(echo "$line" | jq -r '.[2]' 2>/dev/null)
            local message=$(echo "$line" | jq -r '.[3]' 2>/dev/null)
            if [[ "$success" == "true" ]]; then
                print_success "Event published: ${event_id:0:16}..."
            else
                print_error "Event publish failed: ${event_id:0:16}... - $message"
            fi
            
        else
            # Unknown message type - just show it
            print_info "Relay message: $line"
        fi
    done
}

# Main function
main() {
    print_header "Persistent Subscription Test - Subscribe to All Events"
    
    # Check dependencies
    if ! command -v websocat &> /dev/null; then
        print_error "websocat command not found"
        print_info "Please install websocat for testing"
        return 1
    fi
    if ! command -v jq &> /dev/null; then
        print_error "jq command not found"
        print_info "Please install jq for JSON processing"
        return 1
    fi
    
    print_info "Subscription ID: $SUBSCRIPTION_ID"
    print_info "Relay URL: $RELAY_URL"
    print_info "Filter: {} (all events)"
    echo
    
    # Create REQ message to subscribe to all events
    local req_message="[\"REQ\",\"$SUBSCRIPTION_ID\",{}]"
    
    print_info "Establishing persistent subscription..."
    print_info "Press Ctrl+C to stop and cleanup"
    echo
    
    # Start websocat connection and keep it open
    {
        echo "$req_message"
        # Keep the connection alive by sleeping indefinitely
        # The connection will receive events as they come in
        while true; do
            sleep 1
        done
    } | websocat "$RELAY_URL" | parse_events &
    
    # Store the background process ID
    WEBSOCAT_PID=$!
    
    # Wait for the background process (which runs indefinitely)
    # This will exit when we get a signal (Ctrl+C)
    wait "$WEBSOCAT_PID" 2>/dev/null || true
}

# Usage information
usage() {
    echo "Usage: $0"
    echo
    echo "This script creates a persistent subscription to all events on the relay"
    echo "and displays them in real-time as they arrive. Perfect for testing"
    echo "the persistent subscription functionality."
    echo
    echo "To test:"
    echo "1. Run this script in one terminal"
    echo "2. Run 'tests/1_nip_test.sh' in another terminal"
    echo "3. Watch events appear in real-time in this terminal"
    echo
    echo "Press Ctrl+C to stop and cleanup the subscription."
}

# Handle help flag
if [[ "$1" == "-h" || "$1" == "--help" ]]; then
    usage
    exit 0
fi

# Run main function
main "$@"