#!/bin/bash
# Complete RPC Translator Deployment Script
# Handles SSH setup, deployment, configuration, and service startup

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[⚠]${NC} $1"; }
log_error() { echo -e "${RED}[✗]${NC} $1"; }
log_section() { echo -e "${CYAN}════════════════════════════════════════${NC}"; }

# VMID configuration
declare -A VMIDS=(
  ["2400"]="192.168.11.240"
  ["2401"]="192.168.11.241"
  ["2402"]="192.168.11.242"
)

PROXMOX_HOST="${PROXMOX_HOST:-192.168.11.10}"
DEPLOY_DIR="/opt/rpc-translator-138"

# Function to check if we can access VMID via pct
check_pct_access() {
    local vmid="$1"
    local vmip="$2"
    
    # Try to find which node has this VMID
    local node=""
    for n in ml110 r630-01 r630-02; do
        if ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@"$PROXMOX_HOST" \
            "pvesh get /nodes/$n/lxc/$vmid/status/current --output-format json >/dev/null 2>&1" 2>/dev/null; then
            node="$n"
            break
        fi
    done
    
    if [ -n "$node" ]; then
        echo "$node"
        return 0
    fi
    return 1
}

# Global variable to store deployed ports
declare -A DEPLOYED_PORTS

# Function to deploy to VMID using pct
deploy_via_pct() {
    local vmid="$1"
    local vmip="$2"
    local node="$3"
    
    log_info "Deploying to VMID $vmid via pct on node $node..."
    
    # Check if dist exists, if not try to build
    cd "$PROJECT_DIR"
    if [ ! -d "$PROJECT_DIR/dist" ]; then
        log_info "dist directory not found, building TypeScript..."
        if command -v node >/dev/null 2>&1; then
            if command -v pnpm >/dev/null 2>&1; then
                pnpm run build 2>&1 || npm run build 2>&1 || true
            else
                npm run build 2>&1 || true
            fi
        else
            log_warn "Node.js not found locally. Will build on target VMID."
        fi
    else
        log_success "Using existing dist directory"
    fi
    
    # Check if Node.js is installed on target
    log_info "Checking Node.js on VMID $vmid..."
    NODE_VERSION=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- node --version 2>/dev/null || echo 'not_installed'" 2>/dev/null || echo "not_installed")
    
    if [ "$NODE_VERSION" = "not_installed" ]; then
        log_warn "Node.js not found on VMID $vmid. Installing..."
        ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- bash -c 'curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs'" 2>/dev/null || {
            log_error "Failed to install Node.js"
            return 1
        }
    fi
    
    # Create deployment directory
    log_info "Creating deployment directory..."
    ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- mkdir -p $DEPLOY_DIR" 2>/dev/null || return 1
    
    # Copy files using tar pipe (more reliable than pct push)
    log_info "Copying files to VMID $vmid..."
    
    # Copy essential files: package.json, env.template
    log_info "Copying package.json and env.template..."
    tar -czf - -C "$PROJECT_DIR" package.json env.template 2>/dev/null | \
    ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- bash -c 'mkdir -p $DEPLOY_DIR && cd $DEPLOY_DIR && tar -xzf -'" 2>/dev/null || {
        log_error "Failed to copy package.json and env.template"
        return 1
    }
    
    # Verify files were copied
    PACKAGE_EXISTS=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- test -f $DEPLOY_DIR/package.json && echo 'yes' || echo 'no'" 2>/dev/null || echo "no")
    
    if [ "$PACKAGE_EXISTS" != "yes" ]; then
        log_error "package.json not found after copy"
        return 1
    fi
    log_success "Files copied successfully"
    
    # Copy dist directory or build on target
    if [ -d "$PROJECT_DIR/dist" ]; then
        log_info "Copying dist directory..."
        ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- mkdir -p $DEPLOY_DIR/dist" 2>/dev/null || return 1
        
        # Copy dist files - preserve structure
        tar -czf - -C "$PROJECT_DIR" dist/ 2>/dev/null | \
        ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- bash -c 'cd $DEPLOY_DIR && tar -xzf - && ls -la dist/ 2>&1 | head -10'" 2>/dev/null || return 1
        
        # Verify main.js exists
        MAIN_JS=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- find $DEPLOY_DIR/dist -name 'main.js' -type f 2>/dev/null | head -1" 2>/dev/null || echo "")
        
        if [ -z "$MAIN_JS" ]; then
            log_error "main.js not found in dist directory"
            log_info "Checking dist structure..."
            ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
                "pct exec $vmid -- find $DEPLOY_DIR/dist -type f 2>/dev/null | head -10" 2>/dev/null || true
            return 1
        fi
        log_success "Found main.js at: $MAIN_JS"
    else
        log_warn "dist directory not found locally, will build on target..."
        # Copy source files and build on target
        ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- mkdir -p $DEPLOY_DIR/src" 2>/dev/null || return 1
        
        # Copy source and tsconfig
        tar -czf - -C "$PROJECT_DIR" src/ tsconfig.json 2>/dev/null | \
        ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- bash -c 'cd $DEPLOY_DIR && tar -xzf -'" 2>/dev/null || return 1
        
        # Build on target
        log_info "Building TypeScript on target VMID..."
        ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- bash -c 'cd $DEPLOY_DIR && npm install typescript --save-dev && npx tsc'" 2>/dev/null || {
            log_error "Build failed on target"
            return 1
        }
    fi
    
    # Install dependencies
    log_info "Installing dependencies..."
    INSTALL_OUTPUT=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- bash -c 'cd $DEPLOY_DIR && npm install --production 2>&1'" 2>/dev/null)
    INSTALL_EXIT=$?
    
    if [ $INSTALL_EXIT -ne 0 ]; then
        log_error "Dependency installation failed"
        log_info "Output: $INSTALL_OUTPUT"
        return 1
    fi
    log_success "Dependencies installed"
    
    # Copy systemd service (with corrected path)
    log_info "Installing systemd service..."
    # Read service file and fix the path
    SERVICE_CONTENT=$(cat "$PROJECT_DIR/systemd/rpc-translator-138.service" | sed 's|dist/main.js|dist/src/main.js|g')
    ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- bash -c 'cat > /etc/systemd/system/rpc-translator-138.service <<\"EOFSERVICE\"
$SERVICE_CONTENT
EOFSERVICE
'" 2>/dev/null || {
        log_warn "Failed to copy systemd service via exec, trying pct push..."
        # Create temp file with corrected path
        TEMP_SERVICE=$(mktemp)
        sed 's|dist/main.js|dist/src/main.js|g' "$PROJECT_DIR/systemd/rpc-translator-138.service" > "$TEMP_SERVICE"
        ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct push $vmid $TEMP_SERVICE /etc/systemd/system/rpc-translator-138.service" 2>/dev/null || return 1
        rm -f "$TEMP_SERVICE"
    }
    
    # Create .env file if it doesn't exist
    log_info "Configuring .env file..."
    ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- bash -c 'if [ ! -f $DEPLOY_DIR/.env ]; then cp $DEPLOY_DIR/env.template $DEPLOY_DIR/.env; fi'" 2>/dev/null || return 1
    
    # Check if port 9545 is in use, if so use alternative port
    log_info "Checking port availability..."
    PORT_IN_USE=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- ss -tlnp 2>/dev/null | grep -q ':9545 ' && echo 'yes' || echo 'no'" 2>/dev/null || echo "no")
    
    if [ "$PORT_IN_USE" = "yes" ]; then
        log_warn "Port 9545 is in use, checking for alternative port..."
        # Try 9547, 9548, etc.
        ALT_PORT=9547
        ALT_WS_PORT=9548
        while ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- ss -tlnp 2>/dev/null | grep -q ':$ALT_PORT '" 2>/dev/null; do
            ALT_PORT=$((ALT_PORT + 2))
            ALT_WS_PORT=$((ALT_WS_PORT + 2))
        done
        log_info "Using alternative ports: HTTP $ALT_PORT, WS $ALT_WS_PORT"
        HTTP_PORT=$ALT_PORT
        WS_PORT=$ALT_WS_PORT
    else
        HTTP_PORT=9545
        WS_PORT=9546
    fi
    
    # Store ports for summary
    DEPLOYED_PORTS[$vmid]="$HTTP_PORT:$WS_PORT"
    
    # Update .env with correct values
    log_info "Updating .env configuration..."
    ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- bash -c 'cat > $DEPLOY_DIR/.env <<EOF
# Server Configuration
HTTP_PORT=$HTTP_PORT
WS_PORT=$WS_PORT
NODE_ENV=production

# Besu Upstream Configuration
BESU_HTTP_URLS=http://127.0.0.1:8545
BESU_WS_URLS=ws://127.0.0.1:8546
CHAIN_ID=138

# Web3Signer Configuration (VMID 107)
WEB3SIGNER_URL=http://192.168.11.111:9000
WEB3SIGNER_TIMEOUT=5000

# Redis Configuration (VMID 106)
REDIS_HOST=192.168.11.110
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
REDIS_KEY_PREFIX=rpc-translator:138

# Vault Configuration (VMID 108) - Optional
VAULT_ADDR=http://192.168.11.112:8200
VAULT_ROLE_ID=
VAULT_SECRET_ID=
VAULT_PATH_TRANSLATOR_CONFIG=secret/data/chain138/translator

# Translator Policy
WALLET_ALLOWLIST=
MAX_GAS_LIMIT=30000000
MAX_GAS_PRICE_WEI=100000000000
MIN_GAS_PRICE_WEI=1000000000
EOF
'" 2>/dev/null || return 1
    
    # Reload systemd and enable service
    log_info "Enabling systemd service..."
    DAEMON_RELOAD=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- systemctl daemon-reload 2>&1" 2>/dev/null)
    if [ $? -ne 0 ]; then
        log_error "Failed to reload systemd: $DAEMON_RELOAD"
        return 1
    fi
    
    ENABLE_OUTPUT=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- systemctl enable rpc-translator-138.service 2>&1" 2>/dev/null)
    if [ $? -ne 0 ]; then
        log_error "Failed to enable service: $ENABLE_OUTPUT"
        # Check if service file exists
        SERVICE_EXISTS=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- test -f /etc/systemd/system/rpc-translator-138.service && echo 'yes' || echo 'no'" 2>/dev/null || echo "no")
        if [ "$SERVICE_EXISTS" != "yes" ]; then
            log_error "Service file not found at /etc/systemd/system/rpc-translator-138.service"
        fi
        return 1
    fi
    log_success "Service enabled"
    
    # Start service
    log_info "Starting service..."
    ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- systemctl start rpc-translator-138.service" 2>/dev/null || {
        log_warn "Service start failed, checking status..."
        ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- systemctl status rpc-translator-138.service --no-pager -l | head -20" 2>/dev/null || true
        return 1
    }
    
    # Wait a moment for service to start
    sleep 2
    
    # Check service status
    log_info "Checking service status..."
    SERVICE_STATUS=$(ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
        "pct exec $vmid -- systemctl is-active rpc-translator-138.service 2>/dev/null || echo 'inactive'" 2>/dev/null || echo "unknown")
    
    if [ "$SERVICE_STATUS" = "active" ]; then
        log_success "Service is running on VMID $vmid"
    else
        log_warn "Service status: $SERVICE_STATUS"
        log_info "Checking logs..."
        ssh -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" \
            "pct exec $vmid -- journalctl -u rpc-translator-138.service --no-pager -n 20" 2>/dev/null || true
    fi
    
    # Test endpoint
    log_info "Testing HTTP endpoint on port $HTTP_PORT..."
    sleep 2
    HTTP_RESPONSE=$(curl -s -X POST "http://${vmip}:${HTTP_PORT}" \
        -H 'Content-Type: application/json' \
        -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' 2>/dev/null || echo "")
    
    if echo "$HTTP_RESPONSE" | grep -q "0x8a"; then
        log_success "HTTP endpoint responding correctly on VMID $vmid (port $HTTP_PORT)"
    else
        log_warn "HTTP endpoint test failed or not ready yet"
        log_info "Response: $HTTP_RESPONSE"
        # Check if service is still starting
        sleep 2
        HTTP_RESPONSE2=$(curl -s -X POST "http://${vmip}:${HTTP_PORT}" \
            -H 'Content-Type: application/json' \
            -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' 2>/dev/null || echo "")
        if echo "$HTTP_RESPONSE2" | grep -q "0x8a"; then
            log_success "HTTP endpoint now responding on VMID $vmid (port $HTTP_PORT)"
        fi
    fi
    
    return 0
}

# Main deployment
log_section
log_info "RPC Translator Service - Complete Deployment"
log_section
echo ""

# Check prerequisites
log_info "Checking prerequisites..."
if ! ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@"$PROXMOX_HOST" "echo 'Connected'" >/dev/null 2>&1; then
    log_error "Cannot connect to Proxmox host $PROXMOX_HOST"
    exit 1
fi
log_success "Proxmox host accessible"
echo ""

# Deploy to each VMID
FAILED_VMIDS=()
SUCCESS_VMIDS=()

for VMID in "${!VMIDS[@]}"; do
    VMIP="${VMIDS[$VMID]}"
    
    log_section
    log_info "Deploying to VMID $VMID ($VMIP)"
    log_section
    echo ""
    
    # Try to find node
    NODE=$(check_pct_access "$VMID" "$VMIP" 2>/dev/null || echo "")
    
    if [ -z "$NODE" ]; then
        log_warn "Could not find VMID $VMID via pct, trying direct SSH..."
        # Try direct deployment via SSH
        if deploy_via_pct "$VMID" "$VMIP" "direct" 2>/dev/null; then
            SUCCESS_VMIDS+=("$VMID")
        else
            log_error "Failed to deploy to VMID $VMID"
            FAILED_VMIDS+=("$VMID")
        fi
    else
        if deploy_via_pct "$VMID" "$VMIP" "$NODE"; then
            SUCCESS_VMIDS+=("$VMID")
        else
            log_error "Failed to deploy to VMID $VMID"
            FAILED_VMIDS+=("$VMID")
        fi
    fi
    
    echo ""
done

# Summary
log_section
log_info "Deployment Summary"
log_section
echo ""

if [ ${#SUCCESS_VMIDS[@]} -gt 0 ]; then
    log_success "Successfully deployed to: ${SUCCESS_VMIDS[*]}"
    echo ""
    log_info "Service endpoints:"
    for vmid in "${SUCCESS_VMIDS[@]}"; do
        vmip="${VMIDS[$vmid]}"
        ports="${DEPLOYED_PORTS[$vmid]:-9545:9546}"
        http_port="${ports%%:*}"
        ws_port="${ports#*:}"
        echo "  VMID $vmid: http://${vmip}:${http_port} (HTTP), ws://${vmip}:${ws_port} (WebSocket)"
    done
    echo ""
fi

if [ ${#FAILED_VMIDS[@]} -gt 0 ]; then
    log_error "Failed to deploy to: ${FAILED_VMIDS[*]}"
    echo ""
    log_info "To retry deployment:"
    for vmid in "${FAILED_VMIDS[@]}"; do
        vmip="${VMIDS[$vmid]}"
        echo "  ./scripts/deploy-to-vmid.sh $vmid $vmip"
    done
    echo ""
fi

log_section
log_info "Deployment Complete"
log_section
echo ""
