#!/usr/bin/env bash
# Add ingress rule for VMID 2400 Cloudflare Tunnel
# Usage: ./add-vmid2400-ingress.sh

set -euo pipefail

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

# Load environment variables
if [[ -f ".env" ]]; then
    source .env
fi

# Tunnel configuration
TUNNEL_ID="26138c21-db00-4a02-95db-ec75c07bda5b"
HOSTNAME="rpc.public-0138.defi-oracle.io"
SERVICE="http://127.0.0.1:8545"

# Cloudflare API configuration
CLOUDFLARE_API_TOKEN="${CLOUDFLARE_API_TOKEN:-}"
CLOUDFLARE_ACCOUNT_ID="${CLOUDFLARE_ACCOUNT_ID:-}"
CLOUDFLARE_EMAIL="${CLOUDFLARE_EMAIL:-}"
CLOUDFLARE_API_KEY="${CLOUDFLARE_API_KEY:-}"

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

info() { echo -e "${GREEN}[INFO]${NC} $1"; }
error() { echo -e "${RED}[ERROR]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }

# Check for required tools
if ! command -v curl >/dev/null 2>&1; then
    error "curl is required"
    exit 1
fi

if ! command -v jq >/dev/null 2>&1; then
    error "jq is required. Install with: apt-get install jq"
    exit 1
fi

# Validate credentials
if [[ -z "$CLOUDFLARE_API_TOKEN" ]] && [[ -z "$CLOUDFLARE_ACCOUNT_ID" ]]; then
    if [[ -z "$CLOUDFLARE_API_KEY" ]] || [[ -z "$CLOUDFLARE_EMAIL" ]]; then
        error "Cloudflare API credentials not found!"
        error "Set CLOUDFLARE_API_TOKEN or CLOUDFLARE_EMAIL + CLOUDFLARE_API_KEY in .env"
        exit 1
    fi
fi

# Get account ID if not set
if [[ -z "$CLOUDFLARE_ACCOUNT_ID" ]]; then
    info "Getting account ID..."
    
    if [[ -n "$CLOUDFLARE_API_TOKEN" ]]; then
        RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
            -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
            -H "Content-Type: application/json")
        
        CLOUDFLARE_ACCOUNT_ID=$(echo "$RESPONSE" | jq -r '.result.id // empty' 2>/dev/null || echo "")
        
        if [[ -z "$CLOUDFLARE_ACCOUNT_ID" ]]; then
            # Try getting from accounts list
            RESPONSE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts" \
                -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \
                -H "Content-Type: application/json")
            CLOUDFLARE_ACCOUNT_ID=$(echo "$RESPONSE" | jq -r '.result[0].id // empty' 2>/dev/null || echo "")
        fi
    fi
    
    if [[ -z "$CLOUDFLARE_ACCOUNT_ID" ]]; then
        error "Could not determine account ID"
        error "Please set CLOUDFLARE_ACCOUNT_ID in .env file"
        exit 1
    fi
fi

info "Account ID: $CLOUDFLARE_ACCOUNT_ID"
info "Tunnel ID: $TUNNEL_ID"

# Get current tunnel configuration
info "Fetching current tunnel configuration..."

if [[ -n "$CLOUDFLARE_API_TOKEN" ]]; then
    AUTH_HEADER="Authorization: Bearer ${CLOUDFLARE_API_TOKEN}"
else
    AUTH_HEADER="X-Auth-Email: ${CLOUDFLARE_EMAIL}"
    AUTH_KEY_HEADER="X-Auth-Key: ${CLOUDFLARE_API_KEY}"
fi

CURRENT_CONFIG=$(curl -s -X GET \
    "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/cfd_tunnel/${TUNNEL_ID}/configurations" \
    -H "$AUTH_HEADER" \
    ${AUTH_KEY_HEADER:+-H "$AUTH_KEY_HEADER"} \
    -H "Content-Type: application/json")

# Check if we got valid response
if ! echo "$CURRENT_CONFIG" | jq -e . >/dev/null 2>&1; then
    error "Failed to fetch tunnel configuration"
    error "Response: $CURRENT_CONFIG"
    exit 1
fi

# Extract current ingress rules
CURRENT_INGRESS=$(echo "$CURRENT_CONFIG" | jq -r '.result.config.ingress // []' 2>/dev/null || echo "[]")

info "Current ingress rules: $(echo "$CURRENT_INGRESS" | jq '. | length')"

# Check if rule already exists
EXISTING_RULE=$(echo "$CURRENT_INGRESS" | jq -r ".[] | select(.hostname == \"$HOSTNAME\") | .hostname" 2>/dev/null || echo "")

if [[ -n "$EXISTING_RULE" ]]; then
    warn "Ingress rule for $HOSTNAME already exists"
    info "Updating existing rule..."
    
    # Remove existing rule, keep others, ensure catch-all is last
    UPDATED_INGRESS=$(echo "$CURRENT_INGRESS" | jq \
        --arg hostname "$HOSTNAME" \
        --arg service "$SERVICE" \
        '[.[] | select(.hostname != $hostname and .service != "http_status:404")] + [{"hostname": $hostname, "service": $service, "originRequest": {"noTLSVerify": true}}] + [{"service": "http_status:404"}]')
else
    info "Adding new ingress rule..."
    
    # Add new rule, ensure catch-all is last
    UPDATED_INGRESS=$(echo "$CURRENT_INGRESS" | jq \
        --arg hostname "$HOSTNAME" \
        --arg service "$SERVICE" \
        '[.[] | select(.service != "http_status:404")] + [{"hostname": $hostname, "service": $service, "originRequest": {"noTLSVerify": true}}] + [{"service": "http_status:404"}]')
fi

# Create config JSON
CONFIG_DATA=$(echo "$UPDATED_INGRESS" | jq -c '{
    config: {
        ingress: .
    }
}')

info "Updating tunnel configuration..."
info "New ingress rules:"
echo "$UPDATED_INGRESS" | jq -r '.[] | "  - \(.hostname // "catch-all"): \(.service)"'

# Update tunnel configuration
RESPONSE=$(curl -s -X PUT \
    "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/cfd_tunnel/${TUNNEL_ID}/configurations" \
    -H "$AUTH_HEADER" \
    ${AUTH_KEY_HEADER:+-H "$AUTH_KEY_HEADER"} \
    -H "Content-Type: application/json" \
    -d "$CONFIG_DATA")

# Check response
if echo "$RESPONSE" | jq -e '.success == true' >/dev/null 2>&1; then
    info "✓ Ingress rule added successfully!"
    info "  $HOSTNAME → $SERVICE"
    echo ""
    info "Configuration will propagate within 1-2 minutes"
    info "Test with: curl -X POST https://$HOSTNAME -H 'Content-Type: application/json' -d '{\"jsonrpc\":\"2.0\",\"method\":\"eth_chainId\",\"params\":[],\"id\":1}'"
else
    error "Failed to add ingress rule"
    ERRORS=$(echo "$RESPONSE" | jq -r '.errors[]?.message // .error // "Unknown error"' 2>/dev/null | head -3)
    error "Errors: $ERRORS"
    error "Response: $RESPONSE"
    exit 1
fi
