#!/bin/bash

# Mission Control Phase 3: Notification Delivery Daemon
# Polls undelivered notifications and sends them to agent sessions via OpenClaw
#
# Usage:
#   scripts/notification-daemon.sh [options]
#
# Options:
#   --agent AGENT_NAME    Only deliver notifications to specific agent
#   --limit N             Max notifications to process per batch (default: 50)
#   --dry-run            Test mode - don't actually deliver notifications
#   --daemon             Run in daemon mode (continuous polling)
#   --interval SECONDS   Polling interval in daemon mode (default: 60)

set -e

# Configuration
MISSION_CONTROL_URL="${MISSION_CONTROL_URL:-http://localhost:3000}"
LOG_DIR="${LOG_DIR:-$HOME/.mission-control/logs}"
LOG_FILE="$LOG_DIR/notification-daemon-$(date +%Y-%m-%d).log"
PID_FILE="/tmp/notification-daemon.pid"
DEFAULT_INTERVAL=60
DEFAULT_LIMIT=50

# Command line options
AGENT_FILTER=""
LIMIT=$DEFAULT_LIMIT
DRY_RUN=false
DAEMON_MODE=false
INTERVAL=$DEFAULT_INTERVAL

# Ensure log directory exists
mkdir -p "$LOG_DIR"

# Logging function
log() {
    local level="$1"
    shift
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $*" | tee -a "$LOG_FILE"
}

# Check if Mission Control is running
check_mission_control() {
    if ! curl -s "$MISSION_CONTROL_URL/api/status" > /dev/null 2>&1; then
        log "ERROR" "Mission Control not accessible at $MISSION_CONTROL_URL"
        return 1
    fi
    return 0
}

# Process and deliver notifications
deliver_notifications() {
    log "INFO" "Starting notification delivery batch"
    
    # Build API request
    local api_payload="{\"limit\": $LIMIT"
    
    if [[ -n "$AGENT_FILTER" ]]; then
        api_payload+=", \"agent_filter\": \"$AGENT_FILTER\""
    fi
    
    if [[ "$DRY_RUN" == "true" ]]; then
        api_payload+=", \"dry_run\": true"
    fi
    
    api_payload+="}"
    
    # Call notification delivery endpoint
    local response
    response=$(curl -s -w "HTTP_STATUS:%{http_code}" \
        -X POST \
        -H "Content-Type: application/json" \
        -d "$api_payload" \
        "$MISSION_CONTROL_URL/api/notifications/deliver" 2>/dev/null)
    
    local http_code
    http_code=$(echo "$response" | grep -o "HTTP_STATUS:[0-9]*" | cut -d: -f2)
    local body
    body=$(echo "$response" | sed 's/HTTP_STATUS:[0-9]*$//')
    
    if [[ "$http_code" != "200" ]]; then
        log "ERROR" "Notification delivery failed: HTTP $http_code"
        log "ERROR" "Response: $body"
        return 1
    fi
    
    # Parse results
    local status delivered errors total_processed
    status=$(echo "$body" | jq -r '.status // "unknown"' 2>/dev/null || echo "parse_error")
    delivered=$(echo "$body" | jq -r '.delivered // 0' 2>/dev/null || echo "0")
    errors=$(echo "$body" | jq -r '.errors // 0' 2>/dev/null || echo "0")
    total_processed=$(echo "$body" | jq -r '.total_processed // 0' 2>/dev/null || echo "0")
    
    if [[ "$status" == "success" ]]; then
        if [[ "$total_processed" -gt 0 ]]; then
            log "INFO" "Batch completed: $total_processed processed, $delivered delivered, $errors failed"
            
            # Log detailed errors if any
            if [[ "$errors" -gt 0 ]]; then
                local error_details
                error_details=$(echo "$body" | jq -r '.error_details[]? | "- \(.recipient): \(.error)"' 2>/dev/null || echo "")
                if [[ -n "$error_details" ]]; then
                    log "WARN" "Error details:"
                    echo "$error_details" | while read -r line; do
                        log "WARN" "  $line"
                    done
                fi
            fi
        else
            log "INFO" "No notifications to deliver"
        fi
        
        return 0
    else
        log "ERROR" "Unexpected delivery response: $status"
        return 1
    fi
}

# Get delivery statistics
get_delivery_stats() {
    local stats_url="$MISSION_CONTROL_URL/api/notifications/deliver"
    
    if [[ -n "$AGENT_FILTER" ]]; then
        stats_url+="?agent=$AGENT_FILTER"
    fi
    
    local response
    response=$(curl -s "$stats_url" 2>/dev/null)
    
    if [[ $? -eq 0 ]]; then
        echo "$response" | jq -r '
            "Delivery Statistics:",
            "  Total notifications: \(.statistics.total)",
            "  Delivered: \(.statistics.delivered)",
            "  Undelivered: \(.statistics.undelivered)",
            "  Delivery rate: \(.statistics.delivery_rate)%",
            "",
            "Agents with pending notifications:",
            (.agents_with_pending[] | "  \(.recipient): \(.pending_count) pending\(if .session_key then "" else " (no session key)" end)")
        ' 2>/dev/null || echo "Failed to parse statistics"
    else
        echo "Failed to fetch delivery statistics"
    fi
}

# Daemon mode signal handlers
cleanup() {
    log "INFO" "Received shutdown signal, stopping daemon"
    rm -f "$PID_FILE"
    exit 0
}

# Check if daemon is already running
check_daemon() {
    if [[ -f "$PID_FILE" ]]; then
        local old_pid
        old_pid=$(cat "$PID_FILE" 2>/dev/null || echo "")
        
        if [[ -n "$old_pid" ]] && kill -0 "$old_pid" 2>/dev/null; then
            log "ERROR" "Notification daemon already running with PID $old_pid"
            exit 1
        else
            log "WARN" "Stale PID file found, removing"
            rm -f "$PID_FILE"
        fi
    fi
}

# Run in daemon mode
run_daemon() {
    log "INFO" "Starting notification daemon (PID: $$)"
    
    # Check if already running
    check_daemon
    
    # Write PID file
    echo $$ > "$PID_FILE"
    
    # Set up signal handlers
    trap cleanup SIGTERM SIGINT SIGQUIT
    
    # Main daemon loop
    while true; do
        if ! check_mission_control; then
            log "WARN" "Mission Control not accessible, sleeping $INTERVAL seconds"
            sleep "$INTERVAL"
            continue
        fi
        
        # Process notifications
        if deliver_notifications; then
            log "DEBUG" "Delivery batch completed successfully"
        else
            log "WARN" "Delivery batch had errors"
        fi
        
        # Sleep until next cycle
        sleep "$INTERVAL"
    done
}

# Parse command line arguments
parse_args() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            --agent)
                AGENT_FILTER="$2"
                shift 2
                ;;
            --limit)
                LIMIT="$2"
                shift 2
                ;;
            --dry-run)
                DRY_RUN=true
                shift
                ;;
            --daemon)
                DAEMON_MODE=true
                shift
                ;;
            --interval)
                INTERVAL="$2"
                shift 2
                ;;
            --stats)
                get_delivery_stats
                exit 0
                ;;
            --stop)
                if [[ -f "$PID_FILE" ]]; then
                    local pid
                    pid=$(cat "$PID_FILE" 2>/dev/null || echo "")
                    if [[ -n "$pid" ]] && kill -0 "$pid" 2>/dev/null; then
                        kill -TERM "$pid"
                        log "INFO" "Sent stop signal to daemon (PID: $pid)"
                        exit 0
                    else
                        log "WARN" "No running daemon found"
                        rm -f "$PID_FILE"
                        exit 1
                    fi
                else
                    log "WARN" "No daemon PID file found"
                    exit 1
                fi
                ;;
            --help|-h)
                show_help
                exit 0
                ;;
            *)
                echo "Unknown option: $1" >&2
                show_help
                exit 1
                ;;
        esac
    done
}

# Show help
show_help() {
    cat << 'EOF'
Mission Control Notification Delivery Daemon

Usage: notification-daemon.sh [options]

Options:
  --agent AGENT_NAME      Only deliver notifications to specific agent
  --limit N              Max notifications to process per batch (default: 50)
  --dry-run              Test mode - don't actually deliver notifications
  --daemon               Run in daemon mode (continuous polling)
  --interval SECONDS     Polling interval in daemon mode (default: 60)
  --stats                Show delivery statistics and exit
  --stop                 Stop running daemon
  --help, -h             Show this help message

Examples:
  # Single batch delivery
  ./notification-daemon.sh

  # Dry run to test
  ./notification-daemon.sh --dry-run

  # Deliver only to specific agent
  ./notification-daemon.sh --agent "coordinator"

  # Run as daemon
  ./notification-daemon.sh --daemon --interval 30

  # Show statistics
  ./notification-daemon.sh --stats

  # Stop daemon
  ./notification-daemon.sh --stop

Environment variables:
  MISSION_CONTROL_URL    Mission Control base URL (default: http://localhost:3005)

Log files:
  $LOG_DIR/notification-daemon-YYYY-MM-DD.log
EOF
}

# Validate arguments
validate_args() {
    if ! [[ "$LIMIT" =~ ^[1-9][0-9]*$ ]]; then
        log "ERROR" "Invalid limit: $LIMIT (must be positive integer)"
        exit 1
    fi
    
    if ! [[ "$INTERVAL" =~ ^[1-9][0-9]*$ ]]; then
        log "ERROR" "Invalid interval: $INTERVAL (must be positive integer)"
        exit 1
    fi
}

# Main execution
main() {
    parse_args "$@"
    validate_args
    
    if [[ "$DAEMON_MODE" == "true" ]]; then
        run_daemon
    else
        # Single run mode
        log "INFO" "Starting single notification delivery run"
        
        if ! check_mission_control; then
            log "ERROR" "Aborting: Mission Control not accessible"
            exit 1
        fi
        
        if deliver_notifications; then
            log "INFO" "Notification delivery completed successfully"
            exit 0
        else
            log "ERROR" "Notification delivery failed"
            exit 1
        fi
    fi
}

# Run main function
main "$@"
