#!/bin/bash
# NPM to Pi-hole DNS Sync (Pi-hole v6 compatible)
# Syncs Nginx Proxy Manager proxy hosts to Pi-hole local DNS
# All domains point to NPM's IP, not the forward destination
# Supports dual Pi-hole deployment for high availability
#
# Pi-hole v6 changes:
# - Updates /etc/pihole/pihole.toml (dns.hosts array)
# - Updates /etc/pihole/hosts/custom.list (traditional format)

set -e

DRY_RUN=false
if [[ "$1" == "--dry-run" ]]; then
    DRY_RUN=true
fi

# NPM's IP address (where all domains should point)
NPM_IP="10.10.0.16"

# Pi-hole instances
PRIMARY_PIHOLE="10.10.0.16"
SECONDARY_PIHOLE="10.10.0.226"

echo "NPM → Pi-hole DNS Sync (v6 compatible)"
echo "============================================================"

# Query NPM database for all enabled proxy hosts
DOMAINS=$(docker exec nginx-proxy-manager_app_1 python3 -c '
import sqlite3
import json

conn = sqlite3.connect("/data/database.sqlite")
cursor = conn.cursor()
cursor.execute("SELECT domain_names FROM proxy_host WHERE enabled = 1")

domains = []
for (domain_names,) in cursor.fetchall():
    for domain in json.loads(domain_names or "[]"):
        domains.append(domain)

for domain in sorted(domains):
    print(domain)

conn.close()
')

# Count records
RECORD_COUNT=$(echo "$DOMAINS" | wc -l)
echo "Found $RECORD_COUNT enabled proxy hosts"
echo ""
echo "All domains will point to NPM at: $NPM_IP"
echo ""
echo "Domains to sync:"
echo "$DOMAINS" | awk -v ip="$NPM_IP" '{printf "  %-15s %s\n", ip, $0}'

if [ "$DRY_RUN" = true ]; then
    echo ""
    echo "[DRY RUN] Not applying changes"
    exit 0
fi

# Build new custom.list (traditional format)
NEW_DNS="# Pi-hole Local DNS Records
# Auto-synced from Nginx Proxy Manager
# All domains point to NPM at $NPM_IP

"

while IFS= read -r domain; do
    NEW_DNS+="$NPM_IP $domain"$'\n'
done <<< "$DOMAINS"

# Build TOML hosts array
TOML_HOSTS=""
while IFS= read -r domain; do
    TOML_HOSTS+="    \"$NPM_IP $domain\","$'\n'
done <<< "$DOMAINS"
# Remove trailing comma from last entry
TOML_HOSTS=$(echo "$TOML_HOSTS" | sed '$ s/,$//')

echo ""
echo "Syncing to Pi-hole instances..."
echo "============================================================"

# Function to update Pi-hole v6 configuration
update_pihole_v6() {
    local pihole_container="$1"
    local ssh_prefix="$2"  # Empty for local, "ssh user@host" for remote

    # Write to /etc/pihole/hosts/custom.list
    if [ -z "$ssh_prefix" ]; then
        echo "$NEW_DNS" | docker exec -i "$pihole_container" tee /etc/pihole/hosts/custom.list > /dev/null 2>&1
    else
        $ssh_prefix "echo '${NEW_DNS}' | docker exec -i $pihole_container tee /etc/pihole/hosts/custom.list > /dev/null" 2>&1
    fi

    # Update pihole.toml using perl for reliable multi-line regex replacement
    # Escape special characters for perl
    local toml_hosts_perl=$(echo "$TOML_HOSTS" | sed 's/\\/\\\\/g; s/"/\\"/g')

    local perl_cmd="perl -i.bak -0pe 's/hosts\\s*=\\s*\\[[^\\]]*\\]/hosts = [\\n${toml_hosts_perl}\\n  ]/s' /etc/pihole/pihole.toml"

    if [ -z "$ssh_prefix" ]; then
        docker exec "$pihole_container" sh -c "$perl_cmd"
    else
        $ssh_prefix "docker exec $pihole_container sh -c \"$perl_cmd\""
    fi
}

# Sync to primary Pi-hole (local)
echo "Primary Pi-hole ($PRIMARY_PIHOLE):"
if update_pihole_v6 "pihole" ""; then
    if docker exec pihole pihole reloaddns > /dev/null 2>&1; then
        echo "  ✓ Updated $RECORD_COUNT DNS records"
        echo "  ✓ Updated /etc/pihole/hosts/custom.list"
        echo "  ✓ Updated /etc/pihole/pihole.toml"
        echo "  ✓ Reloaded DNS"
    else
        echo "  ✗ Failed to reload DNS"
        PRIMARY_SYNC_FAILED=1
    fi
else
    echo "  ✗ Failed to update Pi-hole configuration"
    PRIMARY_SYNC_FAILED=1
fi

# Sync to secondary Pi-hole (remote via SSH using IP)
echo "Secondary Pi-hole ($SECONDARY_PIHOLE):"
if update_pihole_v6 "pihole" "ssh -o StrictHostKeyChecking=no cal@$SECONDARY_PIHOLE"; then
    if ssh -o StrictHostKeyChecking=no "cal@$SECONDARY_PIHOLE" "docker exec pihole pihole reloaddns > /dev/null" 2>&1; then
        echo "  ✓ Updated $RECORD_COUNT DNS records"
        echo "  ✓ Updated /etc/pihole/hosts/custom.list"
        echo "  ✓ Updated /etc/pihole/pihole.toml"
        echo "  ✓ Reloaded DNS"
    else
        echo "  ✗ Failed to reload DNS"
        SECONDARY_SYNC_FAILED=1
    fi
else
    echo "  ✗ Failed to update Pi-hole configuration or SSH connection issue"
    SECONDARY_SYNC_FAILED=1
fi

echo ""
if [ -z "$PRIMARY_SYNC_FAILED" ] && [ -z "$SECONDARY_SYNC_FAILED" ]; then
    echo "✓ Successfully synced to both Pi-hole instances"
    echo "✓ All $RECORD_COUNT domains now point to NPM at $NPM_IP"
    echo "✓ Updated both pihole.toml and custom.list files"
    exit 0
elif [ -z "$PRIMARY_SYNC_FAILED" ] && [ -n "$SECONDARY_SYNC_FAILED" ]; then
    echo "⚠ Primary sync successful, but secondary sync failed"
    echo "  Check SSH connectivity to $SECONDARY_PIHOLE and secondary Pi-hole health"
    exit 1
elif [ -n "$PRIMARY_SYNC_FAILED" ] && [ -z "$SECONDARY_SYNC_FAILED" ]; then
    echo "⚠ Secondary sync successful, but primary sync failed"
    echo "  Check primary Pi-hole health"
    exit 1
else
    echo "✗ Both Pi-hole syncs failed"
    echo "  Check Pi-hole containers and SSH connectivity"
    exit 2
fi
