#!/bin/bash

# =============================================================================
# Refresh dnsmasq config from /opt/Eye/scripts/print-dnsmasq.pl
# Triggers restart if dhcp-host=, address=, or ptr-record= lines change.
# =============================================================================
# set -euo pipefail  # Fail fast on error, undefined var, or pipe failure

logger -t dnsmasq-refresh "Config refresh requested"

force="${1:-}"

# --- 1. Generate new config ---
/opt/Eye/scripts/print-dnsmasq.pl > /tmp/mac-all.new
ret=$?
if [ ${ret} -ne 0 ]; then
    rm -f /tmp/mac-all.new
    logger -t dnsmasq-refresh "ERROR: Config generation failed (exit $ret). Aborting."
    exit 1
fi

# Ensure target dir exists
[ -d /etc/dnsmasq.d ] || mkdir -p /etc/dnsmasq.d

# --- 2. Compare with current config ---
# Use existing file or empty if missing
current_file="/etc/dnsmasq.d/mac-all"
tmp_new="/tmp/mac-all.new"
tmp_old="/tmp/mac-all.old"

# Always have a baseline for diff (even if file missing)
if [ -f "$current_file" ]; then
    cp "$current_file" "$tmp_old"
else
    touch "$tmp_old"
fi

# Get diff of relevant lines only
diff_output=$(diff -u "$tmp_old" "$tmp_new" 2>/dev/null || true)

# Extract changed lines with our directives
changed_lines=$(echo "$diff_output" | grep -E "^[+-](dhcp-host|address|ptr-record)=" || true)

# Extract MACs (only from dhcp-host) for lease cleanup
changes_macs=$(echo "$changed_lines" | grep "^[+-]dhcp-host=" | \
    sed -E 's/^[+-]dhcp-host=//' | cut -d',' -f1 | \
    grep -Eo '^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$' | sort -u)

# Check if address= or ptr-record= changed
if echo "$changed_lines" | grep -q "^[+-]\(address\|ptr-record\)="; then
    need_restart="yes"
fi

# --- 3. Decide: restart or skip? ---
if [ -n "${changes_macs}" ] || [ -n "${need_restart:-}" ] || [ -n "${force:-}" ]; then
    logger -t dnsmasq-refresh "Changes detected. Updating config..."

    # --- ATOMIC REPLACE: delete → copy ---
    rm -f "$current_file"
    /bin/cp "$tmp_new" "$current_file"

    # --- Validate new config ---
    if /usr/sbin/dnsmasq --test >/dev/null 2>&1; then
        logger -t dnsmasq-refresh "Config OK. Restarting dnsmasq..."

        # Stop dnsmasq
        if ! systemctl stop dnsmasq >/dev/null 2>&1; then
            logger -t dnsmasq-refresh "WARNING: Failed to stop dnsmasq (maybe not running?)"
        fi

        # Clear leases for changed MACs
        if [ -n "${changes_macs}" ] && [ -f /var/lib/misc/dnsmasq.leases ]; then
            while IFS= read -r mac; do
                [ -z "$mac" ] && continue
                logger -t dnsmasq-refresh "Clearing lease for ${mac}"
                sed -i "/${mac}/d" /var/lib/misc/dnsmasq.leases 2>/dev/null || true
            done <<< "${changes_macs}"
        fi

        # Start dnsmasq
        if systemctl start dnsmasq >/dev/null 2>&1; then
            logger -t dnsmasq-refresh "SUCCESS: dnsmasq restarted"
        else
            logger -t dnsmasq-refresh "CRITICAL: dnsmasq failed to start! Rolling back..."
            rm -f "$current_file"
            [ -f "$tmp_old" ] && /bin/cp "$tmp_old" "$current_file"
            systemctl start dnsmasq >/dev/null 2>&1 || \
                logger -t dnsmasq-refresh "Rollback config applied, but dnsmasq still failed to start!"
            exit 1
        fi
    else
        logger -t dnsmasq-refresh "ERROR: dnsmasq config test failed! Rolling back..."
        rm -f "$current_file"
        [ -f "$tmp_old" ] && /bin/cp "$tmp_old" "$current_file"
        systemctl restart dnsmasq >/dev/null 2>&1 || true
        exit 1
    fi
else
    logger -t dnsmasq-refresh "No relevant changes. Skipping restart."
fi

# --- Cleanup ---
rm -f "$tmp_new" "$tmp_old"

logger -t dnsmasq-refresh "Done."

exit 0
