#!/bin/bash

# DNS 同步脚本
# 比较 FTP 根目录的 dns.conf 和本地的 dns.conf，如果有变化则同步到 /etc/resolv.conf

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数 - 输出到 stderr 避免影响函数返回值
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"
REMOTE_DNS_CONF_URL=""
RESOLV_CONF="/etc/resolv.conf"
LOG_FILE="/opt/argus-metric/.dns_sync.log"

# 从环境变量或配置文件获取 FTP 服务器信息
get_ftp_config() {
    # 优先从环境变量获取配置
    log_info "获取 FTP 配置信息..."
    
    # 如果环境变量中没有设置，则尝试从配置文件读取
    if [[ -z "$FTP_SERVER" || -z "$FTP_USER" || -z "$FTP_PASSWORD" ]]; then
        local config_file="$SCRIPT_DIR/config.env"
        if [[ -f "$config_file" ]]; then
            log_info "从配置文件读取 FTP 配置: $config_file"
            source "$config_file"
        fi
    else
        log_info "使用环境变量中的 FTP 配置"
    fi
    
    # 设置默认值（如果环境变量和配置文件都没有设置）
    FTP_SERVER="${FTP_SERVER:-localhost}"
    FTP_USER="${FTP_USER:-ftpuser}"
    FTP_PASSWORD="${FTP_PASSWORD:-ZGClab1234!}"
    
    # 构建远程 DNS 配置文件 URL
    REMOTE_DNS_CONF_URL="ftp://${FTP_USER}:${FTP_PASSWORD}@${FTP_SERVER}/dns.conf"
    
    log_info "FTP 配置来源: ${FTP_CONFIG_SOURCE:-环境变量/配置文件}"
}

# 下载远程 DNS 配置文件
download_remote_dns_conf() {
    local temp_file="/tmp/dns.conf.remote.$$"
    
    log_info "从 FTP 服务器下载 DNS 配置文件..."
    log_info "远程地址: $REMOTE_DNS_CONF_URL"
    log_info "FTP 服务器: $FTP_SERVER"
    log_info "FTP 用户: $FTP_USER"
    
    # 先测试 FTP 连接
    log_info "测试 FTP 连接..."
    if curl -u "${FTP_USER}:${FTP_PASSWORD}" -sfI "ftp://${FTP_SERVER}/" >/dev/null 2>&1; then
        log_success "FTP 服务器连接成功"
    else
        log_error "无法连接到 FTP 服务器: $FTP_SERVER"
        log_error "请检查:"
        log_error "  1. FTP 服务器是否运行"
        log_error "  2. 网络连接是否正常"
        log_error "  3. 服务器地址是否正确"
        return 1
    fi
    
    # 测试 dns.conf 文件是否存在
    log_info "检查远程 dns.conf 文件是否存在..."
    if curl -u "${FTP_USER}:${FTP_PASSWORD}" -sfI "ftp://${FTP_SERVER}/dns.conf" >/dev/null 2>&1; then
        log_success "远程 dns.conf 文件存在"
    else
        log_error "远程 dns.conf 文件不存在或无法访问"
        log_error "请检查 FTP 服务器根目录下是否有 dns.conf 文件"
        return 1
    fi
    
    # 尝试下载文件
    log_info "开始下载 dns.conf 文件..."
    if curl -u "${FTP_USER}:${FTP_PASSWORD}" -sf "ftp://${FTP_SERVER}/dns.conf" -o "$temp_file" 2>/dev/null; then
        log_success "远程 DNS 配置文件下载成功"
        echo "$temp_file"
    else
        log_error "下载 dns.conf 文件失败"
        log_error "尝试手动测试命令:"
        log_error "  curl -u ${FTP_USER}:${FTP_PASSWORD} ftp://${FTP_SERVER}/dns.conf"
        rm -f "$temp_file"
        return 1
    fi
}

# 比较两个文件是否相同
compare_files() {
    local file1="$1"
    local file2="$2"
    
    if [[ ! -f "$file1" || ! -f "$file2" ]]; then
        return 1
    fi
    
    # 使用 diff 比较文件内容
    if diff -q "$file1" "$file2" >/dev/null 2>&1; then
        return 0  # 文件相同
    else
        return 1  # 文件不同
    fi
}

# 将 DNS 配置添加到 /etc/resolv.conf 开头
update_resolv_conf() {
    local dns_conf_file="$1"
    
    log_info "更新 /etc/resolv.conf 文件..."

    # 创建临时文件
    local temp_resolv="/tmp/resolv.conf.$$"

    # 将 dns.conf 内容转换为 nameserver 添加到临时文件开头
    while IFS= read -r line; do
        # 跳过空行和注释
        [[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
        # 验证 IP 格式
        if [[ "$line" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ ]]; then
            echo "nameserver $line" >> "$temp_resolv"
            log_info "添加 DNS 到临时文件: $line"
        else
            log_warning "跳过无效 DNS: $line"
        fi
    done < "$dns_conf_file"

    # 将原 resolv.conf 内容追加到临时文件后面
    if [[ -f "$RESOLV_CONF" ]]; then
        cat "$RESOLV_CONF" >> "$temp_resolv"
    fi

    # 判断是否是 root
    if [[ $(id -u) -eq 0 ]]; then
        # root 直接写入
        tee "$RESOLV_CONF" < "$temp_resolv" >/dev/null
        chmod 644 "$RESOLV_CONF"
    else
        # 非 root 尝试使用 sudo
        if command -v sudo >/dev/null 2>&1; then
            sudo tee "$RESOLV_CONF" < "$temp_resolv" >/dev/null
            sudo chmod 644 "$RESOLV_CONF"
        else
            log_error "非 root 用户且系统未安装 sudo，无法更新 /etc/resolv.conf"
            rm -f "$temp_resolv"
            exit 1
        fi
    fi

    # 清理临时文件
    rm -f "$temp_resolv"

    log_success "/etc/resolv.conf 已更新"
}

# 记录同步日志
log_sync() {
    local message="$1"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] $message" >> "$LOG_FILE"
}

# 主函数
main() {
    log_info "开始 DNS 同步检查..."
    log_sync "DNS 同步检查开始"
    
    # 确保系统目录存在
    mkdir -p "/opt/argus-metric"
    
    # 获取 FTP 配置
    get_ftp_config
    
    # 检查本地 DNS 配置文件是否存在
    if [[ ! -f "$LOCAL_DNS_CONF" ]]; then
        log_warning "本地 DNS 配置文件不存在: $LOCAL_DNS_CONF"
        log_warning "将下载远程配置文件并更新系统 DNS 设置"
        
        # 下载远程配置文件
        if remote_file=$(download_remote_dns_conf); then
            # 复制到本地
            cp "$remote_file" "$LOCAL_DNS_CONF"
            log_success "远程 DNS 配置文件已保存到本地"
            
            # 更新 resolv.conf
            update_resolv_conf "$LOCAL_DNS_CONF"
            log_sync "首次同步完成，DNS 配置已更新"
            
            # 清理临时文件
            rm -f "$remote_file"
        else
            log_error "无法下载远程 DNS 配置文件，同步失败"
            log_sync "同步失败：无法下载远程配置文件"
            exit 1
        fi
    else
        log_info "本地 DNS 配置文件存在: $LOCAL_DNS_CONF"
        
        # 下载远程配置文件进行比较
        if remote_file=$(download_remote_dns_conf); then
            # 比较文件
            if compare_files "$LOCAL_DNS_CONF" "$remote_file"; then
                log_info "DNS 配置文件无变化，无需更新"
                log_sync "DNS 配置文件无变化"
            else
                log_info "检测到 DNS 配置文件有变化，开始同步..."
                log_sync "检测到 DNS 配置文件变化，开始同步"
                
                # 更新本地配置文件
                cp "$remote_file" "$LOCAL_DNS_CONF"
                log_success "本地 DNS 配置文件已更新"
                
                # 更新 resolv.conf
                update_resolv_conf "$LOCAL_DNS_CONF"
                log_sync "DNS 配置同步完成"
            fi
            
            # 清理临时文件
            rm -f "$remote_file"
        else
            log_error "无法下载远程 DNS 配置文件，跳过本次同步"
            log_sync "同步失败：无法下载远程配置文件"
            exit 1
        fi
    fi
    
    log_success "DNS 同步检查完成"
    log_sync "DNS 同步检查完成"
}

# 脚本入口
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    main "$@"
fi
