#!/bin/bash

# Trace DNS to VM Service - Complete Path Analysis
# Reviews all hops and configurations from DNS to VMID 5000

set -uo pipefail

DOMAIN="explorer.d-bis.org"
VM_IP="192.168.11.140"
VMID=5000
NODE="r630-02"
NPMPLUS_IP="192.168.11.166"
NPMPLUS_VMID="10233"

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

echo "=========================================="
echo "DNS to VM Service Path Analysis"
echo "=========================================="
echo "Domain: $DOMAIN"
echo "Target VM: VMID $VMID ($VM_IP) on $NODE"
echo "=========================================="
echo ""

# ============================================
# 1. DNS Resolution
# ============================================
echo -e "${CYAN}=== 1. DNS Resolution ===${NC}"

# Check DNS A record
DNS_IP=$(dig +short $DOMAIN A 2>/dev/null | head -1 || echo "")
if [ -n "$DNS_IP" ]; then
    echo -e "${GREEN}✅ DNS A Record:${NC} $DOMAIN → $DNS_IP"
    
    # Check if it's Cloudflare IP
    if echo "$DNS_IP" | grep -qE "^104\.|^172\.|^198\.|^141\.|^188\."; then
        echo -e "${GREEN}   → Cloudflare IP detected${NC}"
        CLOUDFLARE_IP="$DNS_IP"
    else
        echo -e "${YELLOW}   → Not a Cloudflare IP${NC}"
    fi
else
    echo -e "${RED}❌ DNS A Record: Not found${NC}"
fi

# Check DNS AAAA record (IPv6)
DNS_IPV6=$(dig +short $DOMAIN AAAA 2>/dev/null | head -1 || echo "")
if [ -n "$DNS_IPV6" ]; then
    echo -e "${GREEN}✅ DNS AAAA Record:${NC} $DOMAIN → $DNS_IPV6"
fi

# Check DNS CNAME
DNS_CNAME=$(dig +short $DOMAIN CNAME 2>/dev/null | head -1 || echo "")
if [ -n "$DNS_CNAME" ]; then
    echo -e "${GREEN}✅ DNS CNAME:${NC} $DOMAIN → $DNS_CNAME"
fi

echo ""

# ============================================
# 2. Cloudflare Configuration
# ============================================
echo -e "${CYAN}=== 2. Cloudflare Configuration ===${NC}"

# Check if Cloudflare tunnel is configured
if [ -n "${CLOUDFLARE_IP:-}" ]; then
    echo -e "${GREEN}✅ Domain appears to use Cloudflare${NC}"
    echo "   IP: $CLOUDFLARE_IP"
    
    # Check Cloudflare tunnel status (if accessible)
    if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-01 'pct exec 102 -- systemctl is-active cloudflared 2>/dev/null'" 2>/dev/null | grep -q "active"; then
        echo -e "${GREEN}✅ Cloudflare tunnel service is running${NC}"
    else
        echo -e "${YELLOW}⚠️  Cloudflare tunnel service status unknown${NC}"
    fi
else
    echo -e "${YELLOW}⚠️  Cloudflare IP not detected in DNS${NC}"
fi

echo ""

# ============================================
# 3. NPMplus Configuration
# ============================================
echo -e "${CYAN}=== 3. NPMplus Configuration ===${NC}"

# Check NPMplus service status
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-01 'pct exec $NPMPLUS_VMID -- docker ps | grep -q npmplus'" 2>/dev/null; then
    echo -e "${GREEN}✅ NPMplus container is running${NC}"
else
    echo -e "${RED}❌ NPMplus container not running${NC}"
fi

# Get NPMplus configuration from database
echo "Checking NPMplus proxy host configuration..."
NPMPLUS_CONFIG=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-01 'pct exec $NPMPLUS_VMID -- docker exec npmplus node -e \"
const Database = require('better-sqlite3');
const db = new Database('/data/npmplus/database.sqlite', { readonly: true });
const host = db.prepare('SELECT id, domain_names, forward_scheme, forward_host, forward_port, ssl_forced FROM proxy_host WHERE domain_names LIKE \\\"%$DOMAIN%\\\"').get();
console.log(JSON.stringify(host || {}));
db.close();
\" 2>&1'" 2>/dev/null || echo "{}")

if echo "$NPMPLUS_CONFIG" | jq -e '.forward_host' >/dev/null 2>&1; then
    FORWARD_HOST=$(echo "$NPMPLUS_CONFIG" | jq -r '.forward_host // "unknown"')
    FORWARD_PORT=$(echo "$NPMPLUS_CONFIG" | jq -r '.forward_port // "unknown"')
    FORWARD_SCHEME=$(echo "$NPMPLUS_CONFIG" | jq -r '.forward_scheme // "unknown"')
    SSL_FORCED=$(echo "$NPMPLUS_CONFIG" | jq -r '.ssl_forced // false')
    
    echo -e "${GREEN}✅ NPMplus Proxy Host Configuration:${NC}"
    echo "   Domain: $DOMAIN"
    echo "   Forward Scheme: $FORWARD_SCHEME"
    echo "   Forward Host: $FORWARD_HOST"
    echo "   Forward Port: $FORWARD_PORT"
    echo "   SSL Forced: $SSL_FORCED"
    
    # Verify target matches expected
    if [ "$FORWARD_HOST" = "$VM_IP" ] && [ "$FORWARD_PORT" = "80" ]; then
        echo -e "${GREEN}   → Configuration matches expected target${NC}"
    else
        echo -e "${RED}   → Configuration mismatch! Expected: $VM_IP:80${NC}"
    fi
else
    echo -e "${RED}❌ NPMplus proxy host not found for $DOMAIN${NC}"
fi

# Check NPMplus port 80/443 listening
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-01 'pct exec $NPMPLUS_VMID -- ss -tlnp | grep -qE \":80 |:443 \"'" 2>/dev/null; then
    echo -e "${GREEN}✅ NPMplus listening on ports 80/443${NC}"
else
    echo -e "${RED}❌ NPMplus not listening on ports 80/443${NC}"
fi

echo ""

# ============================================
# 4. Network Routing
# ============================================
echo -e "${CYAN}=== 4. Network Routing ===${NC}"

# Test connectivity from NPMplus to target VM
echo "Testing connectivity from NPMplus to target VM..."
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-01 'pct exec $NPMPLUS_VMID -- curl -s -o /dev/null -w \"%{http_code}\" --connect-timeout 5 http://$VM_IP:80/ 2>/dev/null'" 2>/dev/null | grep -q "200"; then
    echo -e "${GREEN}✅ NPMplus can reach target VM (HTTP 200)${NC}"
else
    HTTP_CODE=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-01 'pct exec $NPMPLUS_VMID -- curl -s -o /dev/null -w \"%{http_code}\" --connect-timeout 5 http://$VM_IP:80/ 2>/dev/null'" 2>/dev/null || echo "000")
    echo -e "${RED}❌ NPMplus cannot reach target VM (HTTP $HTTP_CODE)${NC}"
fi

# Check firewall rules (basic check)
echo "Checking network connectivity..."
if ping -c 1 -W 2 "$VM_IP" >/dev/null 2>&1; then
    echo -e "${GREEN}✅ Target VM is reachable via ping${NC}"
else
    echo -e "${YELLOW}⚠️  Target VM not reachable via ping (may be firewall)${NC}"
fi

echo ""

# ============================================
# 5. Target VM (VMID 5000) Configuration
# ============================================
echo -e "${CYAN}=== 5. Target VM (VMID 5000) Configuration ===${NC}"

# Check container status
CONTAINER_STATUS=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@$NODE 'pct status $VMID 2>/dev/null | awk \"{print \\\$2}\"'" 2>/dev/null || echo "unknown")
if [ "$CONTAINER_STATUS" = "running" ]; then
    echo -e "${GREEN}✅ Container VMID $VMID is running${NC}"
else
    echo -e "${RED}❌ Container VMID $VMID is not running (status: $CONTAINER_STATUS)${NC}"
fi

# Check nginx service
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@$NODE 'pct exec $VMID -- systemctl is-active nginx 2>/dev/null'" 2>/dev/null | grep -q "active"; then
    echo -e "${GREEN}✅ Nginx service is running${NC}"
else
    echo -e "${RED}❌ Nginx service is not running${NC}"
fi

# Check nginx listening ports
NGINX_PORTS=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@$NODE 'pct exec $VMID -- ss -tlnp | grep nginx | grep -oE \":[0-9]+\" | sort -u'" 2>/dev/null || echo "")
if [ -n "$NGINX_PORTS" ]; then
    echo -e "${GREEN}✅ Nginx listening on ports:${NC} $NGINX_PORTS"
    if echo "$NGINX_PORTS" | grep -q ":80"; then
        echo -e "${GREEN}   → Port 80 confirmed${NC}"
    else
        echo -e "${RED}   → Port 80 NOT listening!${NC}"
    fi
else
    echo -e "${RED}❌ Nginx not listening on any ports${NC}"
fi

# Check nginx configuration
echo "Checking nginx configuration..."
NGINX_CONFIG=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@$NODE 'pct exec $VMID -- cat /etc/nginx/sites-available/blockscout 2>/dev/null | head -50'" 2>/dev/null || echo "")

if [ -n "$NGINX_CONFIG" ]; then
    echo -e "${GREEN}✅ Nginx configuration file exists${NC}"
    
    # Check server_name
    if echo "$NGINX_CONFIG" | grep -q "server_name.*$DOMAIN"; then
        echo -e "${GREEN}   → server_name includes $DOMAIN${NC}"
    else
        echo -e "${YELLOW}   → server_name may not include $DOMAIN${NC}"
    fi
    
    # Check listen directives
    if echo "$NGINX_CONFIG" | grep -q "listen.*80"; then
        echo -e "${GREEN}   → Listening on port 80${NC}"
    else
        echo -e "${RED}   → Not listening on port 80!${NC}"
    fi
    
    # Check root location
    if echo "$NGINX_CONFIG" | grep -q "location.*/.*root.*html"; then
        echo -e "${GREEN}   → Root location configured${NC}"
    else
        echo -e "${YELLOW}   → Root location may not be configured${NC}"
    fi
else
    echo -e "${RED}❌ Nginx configuration file not found${NC}"
fi

# Test nginx config validity
if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@$NODE 'pct exec $VMID -- nginx -t 2>&1'" 2>/dev/null | grep -q "test is successful"; then
    echo -e "${GREEN}✅ Nginx configuration is valid${NC}"
else
    echo -e "${RED}❌ Nginx configuration has errors${NC}"
    ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@$NODE 'pct exec $VMID -- nginx -t 2>&1'" 2>/dev/null | head -5
fi

echo ""

# ============================================
# 6. Frontend File Check
# ============================================
echo -e "${CYAN}=== 6. Frontend File Check ===${NC}"

if ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@$NODE 'pct exec $VMID -- test -f /var/www/html/index.html'" 2>/dev/null; then
    echo -e "${GREEN}✅ Frontend file exists${NC}"
    
    FILE_SIZE=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@$NODE 'pct exec $VMID -- stat -c%s /var/www/html/index.html 2>/dev/null'" 2>/dev/null || echo "0")
    echo "   File size: $FILE_SIZE bytes"
    
    FILE_PERMS=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@$NODE 'pct exec $VMID -- ls -l /var/www/html/index.html 2>/dev/null'" 2>/dev/null || echo "")
    if [ -n "$FILE_PERMS" ]; then
        echo "   Permissions: $FILE_PERMS"
    fi
else
    echo -e "${RED}❌ Frontend file not found${NC}"
fi

echo ""

# ============================================
# 7. End-to-End Test
# ============================================
echo -e "${CYAN}=== 7. End-to-End Connectivity Test ===${NC}"

# Test from local to target
echo "Testing direct access to target VM..."
LOCAL_TEST=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 "http://$VM_IP:80/" 2>/dev/null || echo "000")
if [ "$LOCAL_TEST" = "200" ]; then
    echo -e "${GREEN}✅ Direct access to target VM: HTTP $LOCAL_TEST${NC}"
else
    echo -e "${RED}❌ Direct access to target VM: HTTP $LOCAL_TEST${NC}"
fi

# Test from NPMplus to target
echo "Testing from NPMplus to target VM..."
NPMPLUS_TEST=$(ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no root@192.168.11.10 "ssh -o ConnectTimeout=5 root@r630-01 'pct exec $NPMPLUS_VMID -- curl -s -o /dev/null -w \"%{http_code}\" --connect-timeout 5 http://$VM_IP:80/ 2>/dev/null'" 2>/dev/null || echo "000")
if [ "$NPMPLUS_TEST" = "200" ]; then
    echo -e "${GREEN}✅ NPMplus to target VM: HTTP $NPMPLUS_TEST${NC}"
else
    echo -e "${RED}❌ NPMplus to target VM: HTTP $NPMPLUS_TEST${NC}"
fi

# Test external domain (if accessible)
echo "Testing external domain access..."
EXTERNAL_TEST=$(curl -s -o /dev/null -w '%{http_code}' --connect-timeout 5 --max-time 10 "https://$DOMAIN" 2>/dev/null || echo "000")
if [ "$EXTERNAL_TEST" = "200" ] || [ "$EXTERNAL_TEST" = "301" ] || [ "$EXTERNAL_TEST" = "302" ]; then
    echo -e "${GREEN}✅ External domain access: HTTP $EXTERNAL_TEST${NC}"
elif [ "$EXTERNAL_TEST" = "000" ]; then
    echo -e "${YELLOW}⚠️  External domain access: Timeout/Connection failed${NC}"
else
    echo -e "${YELLOW}⚠️  External domain access: HTTP $EXTERNAL_TEST${NC}"
fi

echo ""

# ============================================
# Summary & Recommendations
# ============================================
echo "=========================================="
echo "Summary & Recommendations"
echo "=========================================="
echo ""

# Check each hop
ISSUES=0

if [ -z "$DNS_IP" ]; then
    echo -e "${RED}❌ DNS: No A record found${NC}"
    ((ISSUES++))
else
    echo -e "${GREEN}✅ DNS: Resolves to $DNS_IP${NC}"
fi

if [ -n "${FORWARD_HOST:-}" ] && [ -n "${FORWARD_PORT:-}" ]; then
    if [ "$FORWARD_HOST" != "$VM_IP" ] || [ "$FORWARD_PORT" != "80" ]; then
    echo -e "${RED}❌ NPMplus: Configuration mismatch${NC}"
    ((ISSUES++))
else
    echo -e "${GREEN}✅ NPMplus: Correctly configured${NC}"
    fi
else
    echo -e "${RED}❌ NPMplus: Configuration not found${NC}"
fi

if [ "$CONTAINER_STATUS" != "running" ]; then
    echo -e "${RED}❌ VM: Container not running${NC}"
    ((ISSUES++))
else
    echo -e "${GREEN}✅ VM: Container running${NC}"
fi

if [ "$LOCAL_TEST" != "200" ]; then
    echo -e "${RED}❌ Service: Not responding on port 80${NC}"
    ((ISSUES++))
else
    echo -e "${GREEN}✅ Service: Responding correctly${NC}"
fi

echo ""
if [ $ISSUES -eq 0 ]; then
    echo -e "${GREEN}✅ All hops are configured correctly!${NC}"
    echo ""
    echo "If external access is still not working, check:"
    echo "  1. Cloudflare proxy status (if using Cloudflare)"
    echo "  2. Firewall rules between NPMplus and target VM"
    echo "  3. NPMplus SSL certificate configuration"
else
    echo -e "${RED}❌ Found $ISSUES issue(s) that need to be fixed${NC}"
fi

echo ""
