#!/bin/bash
set -e

# 颜色
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" >&2; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" >&2; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" >&2; }
log_error() { echo -e "${RED}[ERROR]${NC} $1" >&2; }

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOCAL_DNS_CONF="/opt/argus-metric/dns.conf"
RESOLV_CONF="/etc/resolv.conf"
ALT_RESOLV_CONF="/run/resolv.conf"
LOG_FILE="/opt/argus-metric/.dns_sync.log"
REMOTE_DNS_CONF_URL=""

# 获取 FTP 配置
get_ftp_config() {
    log_info "获取 FTP 配置信息..."
    if [[ -z "$FTP_SERVER" || -z "$FTP_USER" || -z "$FTP_PASSWORD" ]]; then
        [[ -f "$SCRIPT_DIR/config.env" ]] && source "$SCRIPT_DIR/config.env"
    fi
    FTP_SERVER="${FTP_SERVER:-localhost}"
    FTP_USER="${FTP_USER:-ftpuser}"
    FTP_PASSWORD="${FTP_PASSWORD:-ZGClab1234!}"
    REMOTE_DNS_CONF_URL="ftp://${FTP_USER}:${FTP_PASSWORD}@${FTP_SERVER}/dns.conf"
}

# 下载远程 dns.conf
download_remote_dns_conf() {
    local tmp="/tmp/dns.remote.$$"
    log_info "测试 FTP 连接..."
    if ! curl -u "${FTP_USER}:${FTP_PASSWORD}" -sfI "ftp://${FTP_SERVER}/" >/dev/null; then
        log_error "无法连接到 FTP 服务器: $FTP_SERVER"; return 1
    fi
    if ! curl -u "${FTP_USER}:${FTP_PASSWORD}" -sf "ftp://${FTP_SERVER}/dns.conf" -o "$tmp" 2>/dev/null; then
        log_error "下载 dns.conf 失败"; rm -f "$tmp"; return 1
    fi
    echo "$tmp"
}

# 文件比较
compare_files() { diff -q "$1" "$2" >/dev/null 2>&1; }

# 从 dns.conf 提取有效 IP
get_dns_ips() {
    grep -Eo '^[0-9]{1,3}(\.[0-9]{1,3}){3}$' "$1" | sort -u
}

# 安全更新 resolv.conf（保留符号链接）
update_resolv_conf() {
    local dns_conf="$1"
    local dns_ips
    mapfile -t dns_ips < <(get_dns_ips "$dns_conf")
    [[ ${#dns_ips[@]} -eq 0 ]] && { log_warning "未检测到有效 DNS"; return; }

    local target_file="$RESOLV_CONF"
    if [[ ! -w "$RESOLV_CONF" ]]; then
        log_warning "/etc/resolv.conf 不可写，使用兜底路径 $ALT_RESOLV_CONF"
        target_file="$ALT_RESOLV_CONF"
    fi

    local temp="/tmp/resolv.new.$$"
    cp "$target_file" "${target_file}.backup.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true
    log_info "更新 DNS 配置文件: $target_file"

    # 写入新的 nameserver 行
    for ip in "${dns_ips[@]}"; do
        echo "nameserver $ip"
    done >"$temp"

    # 追加原内容（去掉重复 nameserver）
    grep -v '^nameserver' "$target_file" >>"$temp" 2>/dev/null || true
    awk '!a[$0]++' "$temp" >"${temp}.uniq"

    # ⚙️ 使用 cat 原地覆盖，避免 mv 引发 “设备忙”
    if cat "${temp}.uniq" >"$target_file" 2>/dev/null; then
        chmod 644 "$target_file"
        log_success "DNS 更新完成: ${dns_ips[*]}"
    else
        log_error "无法写入 $target_file，可能被系统锁定"
    fi

    rm -f "$temp" "${temp}.uniq"
}

# 检查 resolv.conf 是否包含 dns.conf 内容
ensure_dns_in_resolv() {
    local dns_conf="$1"
    local dns_ips
    mapfile -t dns_ips < <(get_dns_ips "$dns_conf")
    [[ ${#dns_ips[@]} -eq 0 ]] && return

    for ip in "${dns_ips[@]}"; do
        if ! grep -q "nameserver $ip" "$RESOLV_CONF" 2>/dev/null; then
            log_warning "检测到 /etc/resolv.conf 缺少 $ip，执行兜底修复"
            update_resolv_conf "$dns_conf"
            return
        fi
    done
    log_info "/etc/resolv.conf 已包含所有 DNS"
}

log_sync() { echo "[$(date '+%F %T')] $1" >>"$LOG_FILE"; }

main() {
    log_info "开始 DNS 同步检查..."
    mkdir -p /opt/argus-metric

    get_ftp_config
    local remote_file
    if ! remote_file=$(download_remote_dns_conf); then
        log_error "下载失败"; log_sync "同步失败"; exit 1
    fi

    if [[ ! -f "$LOCAL_DNS_CONF" ]]; then
        log_info "本地 dns.conf 不存在，初始化..."
        cp "$remote_file" "$LOCAL_DNS_CONF"
        update_resolv_conf "$LOCAL_DNS_CONF"
        log_sync "首次同步完成"
    else
        if compare_files "$LOCAL_DNS_CONF" "$remote_file"; then
            log_info "dns.conf 无变化"
            ensure_dns_in_resolv "$LOCAL_DNS_CONF"
            log_sync "dns.conf 无变化，执行兜底检查"
        else
            log_info "检测到 DNS 配置更新"
            cp "$remote_file" "$LOCAL_DNS_CONF"
            update_resolv_conf "$LOCAL_DNS_CONF"
            log_sync "DNS 配置同步完成"
        fi
    fi

    rm -f "$remote_file"
    log_success "DNS 同步流程完成"
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi
