#!/usr/bin/env bash
# Complete Let's Encrypt setup using Cloudflare Tunnel
# Falls back to public IP, then DNS-01 if needed

set -e

VMID=2500
DOMAIN="rpc-core.d-bis.org"
NAME="rpc-core"
IP="192.168.11.250"
PUBLIC_IP="45.49.67.248"
PROXMOX_HOST="192.168.11.10"
TUNNEL_VMID=102

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

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

log_info "Let's Encrypt Setup - Cloudflare Tunnel Method"
log_info "Domain: $DOMAIN"
echo ""

# Load .env
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [ -f "$SCRIPT_DIR/../.env" ]; then
    source "$SCRIPT_DIR/../.env" 2>/dev/null
fi

# Step 1: Configure Cloudflare Tunnel
log_info "Step 1: Configuring Cloudflare Tunnel route..."

# Get tunnel ID from token
if [ -n "$CLOUDFLARE_TUNNEL_TOKEN" ]; then
    TUNNEL_ID=$(echo "$CLOUDFLARE_TUNNEL_TOKEN" | base64 -d 2>/dev/null | python3 -c "import sys, json; data=json.load(sys.stdin); print(data.get('a', ''))" 2>/dev/null || echo "")
    if [ -z "$TUNNEL_ID" ]; then
        # Fallback: use account ID as tunnel ID (they're often the same)
        TUNNEL_ID="${CLOUDFLARE_ACCOUNT_ID:-52ad57a71671c5fc009edf0744658196}"
    fi
    log_info "Tunnel ID: $TUNNEL_ID"
else
    TUNNEL_ID="${CLOUDFLARE_ACCOUNT_ID:-52ad57a71671c5fc009edf0744658196}"
    log_warn "Using account ID as tunnel ID: $TUNNEL_ID"
fi

# Check if tunnel is running
if sshpass -p 'L@kers2010' ssh -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
    "pct exec $TUNNEL_VMID -- systemctl is-active cloudflared >/dev/null 2>&1"; then
    log_success "Cloudflare Tunnel is running"
else
    log_warn "Cloudflare Tunnel may not be running on VMID $TUNNEL_VMID"
fi

# Configure tunnel route via API
if [ -n "$CLOUDFLARE_API_KEY" ] && [ -n "$CLOUDFLARE_EMAIL" ] && [ -n "$CLOUDFLARE_ACCOUNT_ID" ] && [ -n "$TUNNEL_ID" ]; then
    log_info "Configuring tunnel route via API..."
    
    # Get current tunnel config
    TUNNEL_CONFIG=$(curl -s -X GET "https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/cfd_tunnel/$TUNNEL_ID/configurations" \
        -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
        -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
        -H "Content-Type: application/json")
    
    # Check if route already exists in config
    if echo "$TUNNEL_CONFIG" | grep -q "$DOMAIN"; then
        log_info "Tunnel route already exists for $DOMAIN"
    else
        log_info "Adding tunnel route: $DOMAIN → http://$IP:443"
        log_warn "Tunnel route configuration via API is complex - using manual method"
        log_info "Please configure in Cloudflare Dashboard:"
        log_info "  Zero Trust → Networks → Tunnels → Your Tunnel → Configure"
        log_info "  Add Public Hostname: rpc-core.d-bis.org → http://$IP:443"
        log_info ""
        log_info "Continuing with DNS setup (tunnel route can be added manually)..."
    fi
else
    log_warn "Missing credentials for tunnel API configuration"
fi

# Step 2: Update DNS to use Tunnel (CNAME)
log_info ""
log_info "Step 2: Updating DNS to use Cloudflare Tunnel..."

# Delete existing A record if exists
if [ -f "$SCRIPT_DIR/create-dns-record-rpc-core.sh" ]; then
    log_info "Checking existing DNS record..."
    EXISTING_RECORD=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records?name=$DOMAIN" \
        -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
        -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
        -H "Content-Type: application/json")
    
    if echo "$EXISTING_RECORD" | grep -q '"id"'; then
        RECORD_ID=$(echo "$EXISTING_RECORD" | grep -o '"id":"[^"]*' | head -1 | cut -d'"' -f4)
        log_info "Deleting existing A record..."
        curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records/$RECORD_ID" \
            -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
            -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
            -H "Content-Type: application/json" >/dev/null
    fi
fi

# Create CNAME to tunnel
if [ -z "$TUNNEL_ID" ]; then
    log_error "Tunnel ID not found. Cannot create CNAME."
    exit 1
fi
TUNNEL_TARGET="${TUNNEL_ID}.cfargotunnel.com"
log_info "Creating CNAME: $NAME → $TUNNEL_TARGET"

CNAME_RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records" \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
    -H "Content-Type: application/json" \
    --data "{
        \"type\": \"CNAME\",
        \"name\": \"$NAME\",
        \"content\": \"$TUNNEL_TARGET\",
        \"ttl\": 1,
        \"proxied\": true
    }")

if echo "$CNAME_RESPONSE" | grep -q '"success":true'; then
    log_success "CNAME record created (proxied)"
else
    log_error "Failed to create CNAME record"
    log_info "Response: $CNAME_RESPONSE"
    exit 1
fi

# Step 3: Wait for tunnel route to be active
log_info ""
log_info "Step 3: Waiting for tunnel route to be active (10 seconds)..."
sleep 10

# Step 4: Wait for DNS propagation
log_info ""
log_info "Step 4: Waiting for DNS propagation (30 seconds)..."
sleep 30

# Step 5: Try Let's Encrypt HTTP-01 through tunnel
log_info ""
log_info "Step 5: Attempting Let's Encrypt HTTP-01 challenge through tunnel..."
CERTBOT_OUTPUT=$(sshpass -p 'L@kers2010' ssh -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
    "pct exec $VMID -- certbot --nginx \
        --non-interactive \
        --agree-tos \
        --email admin@d-bis.org \
        -d $DOMAIN \
        --redirect 2>&1" || echo "FAILED")

if echo "$CERTBOT_OUTPUT" | grep -q "Successfully received certificate\|Congratulations"; then
    log_success "Certificate obtained via HTTP-01 through tunnel!"
    exit 0
else
    log_warn "HTTP-01 through tunnel failed"
    log_info "Trying fallback: Public IP method..."
fi

# Fallback: Try with public IP
log_info ""
log_info "Fallback: Trying with public IP $PUBLIC_IP..."

# Update DNS to point to public IP
log_info "Updating DNS to point to public IP..."
PUBLIC_IP_RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records/$RECORD_ID" \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
    -H "Content-Type: application/json" \
    --data "{
        \"type\": \"A\",
        \"name\": \"$NAME\",
        \"content\": \"$PUBLIC_IP\",
        \"ttl\": 1,
        \"proxied\": false
    }" 2>/dev/null || curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/dns_records" \
    -H "X-Auth-Email: $CLOUDFLARE_EMAIL" \
    -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
    -H "Content-Type: application/json" \
    --data "{
        \"type\": \"A\",
        \"name\": \"$NAME\",
        \"content\": \"$PUBLIC_IP\",
        \"ttl\": 1,
        \"proxied\": false
    }")

if echo "$PUBLIC_IP_RESPONSE" | grep -q '"success":true'; then
    log_success "DNS updated to public IP"
    sleep 30
    
    CERTBOT_OUTPUT=$(sshpass -p 'L@kers2010' ssh -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
        "pct exec $VMID -- certbot --nginx \
            --non-interactive \
            --agree-tos \
            --email admin@d-bis.org \
            -d $DOMAIN \
            --redirect 2>&1" || echo "FAILED")
    
    if echo "$CERTBOT_OUTPUT" | grep -q "Successfully received certificate\|Congratulations"; then
        log_success "Certificate obtained via HTTP-01 with public IP!"
        exit 0
    else
        log_warn "HTTP-01 with public IP failed"
    fi
else
    log_warn "Failed to update DNS to public IP"
fi

# Final fallback: DNS-01 challenge
log_info ""
log_info "Final fallback: Using DNS-01 challenge..."

# Install DNS plugin
sshpass -p 'L@kers2010' ssh -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
    "pct exec $VMID -- apt-get install -y -qq python3-certbot-dns-cloudflare" || {
    log_error "Failed to install certbot-dns-cloudflare"
    exit 1
}

# Create credentials file
sshpass -p 'L@kers2010' ssh -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
    "pct exec $VMID -- bash -c '
        mkdir -p /etc/cloudflare
        cat > /etc/cloudflare/credentials.ini <<EOF
dns_cloudflare_api_token = ${CLOUDFLARE_API_TOKEN:-}
dns_cloudflare_email = $CLOUDFLARE_EMAIL
dns_cloudflare_api_key = $CLOUDFLARE_API_KEY
EOF
        chmod 600 /etc/cloudflare/credentials.ini
    '"

# Try DNS-01
log_info "Obtaining certificate via DNS-01 challenge..."
CERTBOT_OUTPUT=$(sshpass -p 'L@kers2010' ssh -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
    "pct exec $VMID -- certbot certonly --dns-cloudflare \
        --dns-cloudflare-credentials /etc/cloudflare/credentials.ini \
        --non-interactive \
        --agree-tos \
        --email admin@d-bis.org \
        -d $DOMAIN 2>&1" || echo "FAILED")

if echo "$CERTBOT_OUTPUT" | grep -q "Successfully received certificate\|Congratulations"; then
    log_success "Certificate obtained via DNS-01 challenge!"
    
    # Update Nginx manually
    log_info "Updating Nginx configuration..."
    sshpass -p 'L@kers2010' ssh -o StrictHostKeyChecking=no root@${PROXMOX_HOST} \
        "pct exec $VMID -- bash -c '
            sed -i \"s|ssl_certificate /etc/nginx/ssl/rpc.crt;|ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;|\" /etc/nginx/sites-available/rpc-core
            sed -i \"s|ssl_certificate_key /etc/nginx/ssl/rpc.key;|ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;|\" /etc/nginx/sites-available/rpc-core
            nginx -t && systemctl reload nginx
        '"
    
    log_success "Nginx updated with Let's Encrypt certificate!"
    exit 0
else
    log_error "All methods failed"
    log_info "Output: $CERTBOT_OUTPUT"
    exit 1
fi

