#!/bin/bash

# Test DNS auto-sync functionality using argus_dns_sync.sh
# This test validates the automatic DNS record updates from IP files
# Usage: ./03.5_dns_sync_test.sh

set -e

HOST_DNS_PORT="${HOST_DNS_PORT:-1053}"

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

echo "=== DNS Auto-Sync Functionality Test ==="
echo "Using DNS server localhost:${HOST_DNS_PORT}"

# Check if container is running
if ! docker compose ps | grep -q "Up"; then
    echo "Error: BIND9 container is not running"
    echo "Please start the container first with: ./01_start_container.sh"
    exit 1
fi

# Check if dig is available
if ! command -v dig &> /dev/null; then
    echo "Installing dig (dnsutils)..."
    apt-get update && apt-get install -y dnsutils
fi

# Function to test DNS query
test_dns_query() {
    local hostname="$1"
    local expected_ip="$2"
    local description="$3"

    echo "Testing: $description"
    echo "Query: $hostname.argus.com -> Expected: $expected_ip"

    # Wait a moment for DNS cache
    sleep 2

    result=$(dig @localhost -p "$HOST_DNS_PORT" "$hostname".argus.com A +short 2>/dev/null || echo "QUERY_FAILED")

    if [ "$result" = "$expected_ip" ]; then
        echo "✓ $result"
        return 0
    else
        echo "✗ Got: $result, Expected: $expected_ip"
        return 1
    fi
}

# Function to wait for sync to complete
wait_for_sync() {
    local timeout=15
    local elapsed=0
    echo "Waiting for DNS sync to complete (max ${timeout}s)..."

    while [ $elapsed -lt $timeout ]; do
        if docker compose exec bind9 test -f /var/lock/argus_dns_sync.lock; then
            echo "Sync process is running..."
        else
            echo "Sync completed"
            sleep 2  # Extra wait for DNS propagation
            return 0
        fi
        sleep 2
        elapsed=$((elapsed + 2))
    done

    echo "Warning: Sync may still be running after ${timeout}s"
    return 0
}

echo ""
echo "Step 1: Preparing test environment..."

# Ensure required directories exist
docker compose exec bind9 mkdir -p /private/argus/etc
docker compose exec bind9 mkdir -p /private/argus/bind/.backup

# Backup original configuration if it exists
docker compose exec bind9 test -f /private/argus/bind/db.argus.com && \
    docker compose exec bind9 cp /private/argus/bind/db.argus.com /private/argus/bind/db.argus.com.backup.test || true

# Ensure initial configuration is available (may already be symlinked)
docker compose exec bind9 test -f /private/argus/bind/db.argus.com || \
    docker compose exec bind9 cp /etc/bind/db.argus.com /private/argus/bind/db.argus.com

echo "✓ Test environment prepared"

echo ""
echo "Step 2: Testing initial DNS configuration..."

# Get current IP for web.argus.com (may have been changed by previous tests)
current_web_ip=$(dig @localhost -p "$HOST_DNS_PORT" web.argus.com A +short 2>/dev/null || echo "UNKNOWN")
echo "Current web.argus.com IP: $current_web_ip"

# Test that DNS is working (regardless of specific IP)
if [ "$current_web_ip" = "UNKNOWN" ] || [ -z "$current_web_ip" ]; then
    echo "DNS resolution not working for web.argus.com"
    exit 1
fi

echo "✓ DNS resolution is working"

echo ""
echo "Step 3: Creating IP files for auto-sync..."

# Create test IP files in the watch directory
echo "Creating test1.argus.com with IP 10.0.0.100"
docker compose exec bind9 bash -c 'echo "10.0.0.100" > /private/argus/etc/test1.argus.com'

echo "Creating test2.argus.com with IP 10.0.0.200"
docker compose exec bind9 bash -c 'echo "test2 service running on 10.0.0.200" > /private/argus/etc/test2.argus.com'

echo "Creating api.argus.com with IP 192.168.1.50"
docker compose exec bind9 bash -c 'echo "API server: 192.168.1.50 port 8080" > /private/argus/etc/api.argus.com'

echo "✓ IP files created"

echo ""
echo "Step 4: Checking DNS sync process..."

# Check if DNS sync process is already running (via supervisord)
if docker compose exec bind9 pgrep -f argus_dns_sync.sh > /dev/null; then
    echo "✓ DNS sync process already running (via supervisord)"
else
    echo "Starting DNS sync process manually..."
    # Start the DNS sync process in background if not running
    docker compose exec -d bind9 /usr/local/bin/argus_dns_sync.sh
    echo "✓ DNS sync process started manually"
fi

# Wait for first sync cycle
wait_for_sync

echo ""
echo "Step 5: Testing auto-synced DNS records..."

failed_tests=0

# Test new DNS records created by auto-sync
if ! test_dns_query "test1" "10.0.0.100" "Auto-synced test1.argus.com"; then
    ((failed_tests++))
fi

if ! test_dns_query "test2" "10.0.0.200" "Auto-synced test2.argus.com"; then
    ((failed_tests++))
fi

if ! test_dns_query "api" "192.168.1.50" "Auto-synced api.argus.com"; then
    ((failed_tests++))
fi

# Verify original records still work (use current IP from earlier)
if ! test_dns_query "web" "$current_web_ip" "Original web.argus.com still working"; then
    ((failed_tests++))
fi

if ! test_dns_query "ns1" "127.0.0.1" "Original ns1.argus.com still working"; then
    ((failed_tests++))
fi

echo ""
echo "Step 6: Testing IP update functionality..."

# Update an existing IP file
echo "Updating test1.argus.com IP from 10.0.0.100 to 10.0.0.150"
docker compose exec bind9 bash -c 'echo "10.0.0.150" > /private/argus/etc/test1.argus.com'

# Wait for sync
wait_for_sync

# Test updated record
if ! test_dns_query "test1" "10.0.0.150" "Updated test1.argus.com IP"; then
    ((failed_tests++))
fi

echo ""
echo "Step 7: Testing invalid IP handling..."

# Create file with invalid IP
echo "Creating invalid.argus.com with invalid IP"
docker compose exec bind9 bash -c 'echo "this is not an IP address" > /private/argus/etc/invalid.argus.com'

# Wait for sync (should skip invalid IP)
wait_for_sync

# Verify invalid record was not added (should fail to resolve)
result=$(dig @localhost -p "$HOST_DNS_PORT" invalid.argus.com A +short 2>/dev/null || echo "NO_RESULT")
if [ "$result" = "NO_RESULT" ] || [ -z "$result" ]; then
    echo "✓ Invalid IP correctly ignored"
else
    echo "✗ Invalid IP was processed: $result"
    ((failed_tests++))
fi

echo ""
echo "Step 8: Verifying backup functionality..."

# Check if backups were created
backup_count=$(docker compose exec bind9 ls -1 /private/argus/bind/.backup/ | wc -l || echo "0")
if [ "$backup_count" -gt 0 ]; then
    echo "✓ Configuration backups created ($backup_count files)"
    # Show latest backup
    docker compose exec bind9 ls -la /private/argus/bind/.backup/ | tail -1
else
    echo "✗ No backup files found"
    ((failed_tests++))
fi

echo ""
echo "Step 9: Cleanup..."

# Note: We don't stop the DNS sync process since it's managed by supervisord
echo "Note: DNS sync process will continue running (managed by supervisord)"

# Clean up test files
docker compose exec bind9 rm -f /private/argus/etc/test1.argus.com
docker compose exec bind9 rm -f /private/argus/etc/test2.argus.com
docker compose exec bind9 rm -f /private/argus/etc/api.argus.com
docker compose exec bind9 rm -f /private/argus/etc/invalid.argus.com

# Restore original configuration if backup exists
docker compose exec bind9 test -f /private/argus/bind/db.argus.com.backup.test && \
    docker compose exec bind9 cp /private/argus/bind/db.argus.com.backup.test /private/argus/bind/db.argus.com && \
    docker compose exec bind9 rm /private/argus/bind/db.argus.com.backup.test || true

# Reload original configuration
docker compose exec bind9 /usr/local/bin/reload-bind9.sh

echo "✓ Cleanup completed"

echo ""
echo "=== DNS Auto-Sync Test Summary ==="
if [ $failed_tests -eq 0 ]; then
    echo "✅ All DNS auto-sync tests passed!"
    echo ""
    echo "Validated functionality:"
    echo "  ✓ Automatic DNS record creation from IP files"
    echo "  ✓ IP address extraction from various file formats"
    echo "  ✓ Dynamic DNS record updates"
    echo "  ✓ Invalid IP address handling"
    echo "  ✓ Configuration backup mechanism"
    echo "  ✓ Preservation of existing DNS records"
    echo ""
    echo "The DNS auto-sync functionality is working correctly!"
    exit 0
else
    echo "❌ $failed_tests DNS auto-sync test(s) failed!"
    echo ""
    echo "Please check:"
    echo "  - argus_dns_sync.sh script configuration"
    echo "  - File permissions in /private/argus/etc/"
    echo "  - BIND9 reload functionality"
    echo "  - Network connectivity and DNS resolution"
    exit 1
fi
