# 定义颜色代码
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# warn if no parameter passed
if [[ $# -lt 3 ]]; then
    echo -e "${CYAN}AdGuard Private DDNS 更新脚本 - Linux/Mac 版本${NC}"
    echo -e "${CYAN}用途：自动更新AdGuard Private的DNS解析记录，支持IPv4和IPv6${NC}"
    echo ""
    echo "用法: $0 <base_url> <auth> <ddns_domain>"
    echo ""
    echo -e "${YELLOW}参数说明:${NC}"
    echo "  base_url: AdGuard Private服务地址"
    echo "            示例: https://xxxxxxxx.adguardprivate.com"
    echo "  auth: 用户名和密码, 格式为 username:password"
    echo "        示例: admin:password123"
    echo "  ddns_domain: 需要更新的域名"
    echo "               示例: nas.home"
    echo ""
    echo -e "${GREEN}使用示例:${NC}"
    echo "./update_dns.sh https://xxxxxxxx.adguardprivate.com admin:password123 nas.home"
    echo ""
    echo -e "${YELLOW}故障排查:${NC}"
    echo "1. 检查用户名密码是否正确"
    echo "2. 确认域名格式正确"
    echo "3. 检查网络连接是否正常"
    exit 1
fi

set -euo pipefail

base_url=$1    # 你的 adguardprivate 服务地址
auth=$2        # 用户名和密码, 格式为 username:password
ddns_domain=$3 # 希望使用的域名

# remove last slash if exists from base_url
base_url=${base_url%/}

# 添加调试模式
DEBUG=false

function debug_log() {
    if [[ "$DEBUG" == "true" ]]; then
        echo -e "${CYAN}[DEBUG] $1${NC}"
    fi
}

# Convert auth to base64
auth_base64=$(echo -n $auth | base64)

# 设置curl命令的默认参数
CURL_OPTS="-sS --connect-timeout 10 --max-time 15"

# 测试服务器连接
echo -e "${YELLOW}测试服务器连接...${NC}"
test_connection=""
test_response=$(curl $CURL_OPTS -w "\n%{http_code}" -H "Authorization: Basic ${auth_base64}" ${base_url}/control/status 2>&1)
test_connection=$(echo "$test_response" | tail -n1)
debug_log "服务器连接测试响应码: $test_connection"

if [[ -z "$test_connection" || ! "$test_connection" =~ "200" ]]; then
    echo -e "${RED}无法连接到服务器或认证失败。详细信息：${NC}"
    echo "$(echo "$test_response" | head -n -1)"
    exit 1
fi

echo -e "${GREEN}服务器连接测试成功${NC}"

echo "服务地址: $base_url"
echo "认证信息: [已隐藏]"
echo "DDNS域名: $ddns_domain"

# 获取IP地址时添加错误处理
ipv4=$(curl $CURL_OPTS -4 https://4.ipw.cn) || {
    echo -e "${RED}获取IPv4地址失败${NC}"
    ipv4=""
}

ipv6=$(curl $CURL_OPTS -6 https://6.ipw.cn) || {
    echo -e "${RED}获取IPv6地址失败${NC}"
    ipv6=""
}

# 确保至少有一个IP地址可用
if [[ -z "$ipv4" && -z "$ipv6" ]]; then
    echo -e "${RED}错误：无法获取任何IP地址。请检查网络连接。${NC}"
    exit 1
fi

function update_dns() {
    local domain=$1
    local answer=$2
    local new_ip=$3
    if [[ -z $answer ]]; then
        echo -e "${RED}应答为空${NC}"
        return
    fi
    if [[ $answer != $new_ip ]]; then
        echo -e "${YELLOW}当前IP ($answer) 与新IP ($new_ip) 不同，正在更新...${NC}"
        debug_log "发送更新请求到: ${base_url}/control/rewrite/update"
        response=$(curl $CURL_OPTS -v -X PUT \
            -H "Content-Type: application/json" \
            -H "Authorization: Basic ${auth_base64}" \
            -d "{\"target\": {\"domain\": \"$domain\", \"answer\": \"$answer\"}, \"update\": {\"domain\": \"$domain\", \"answer\": \"$new_ip\"}}" \
            ${base_url}/control/rewrite/update 2>&1)
        debug_log "API响应: $response"
        if [[ $response =~ "200" ]]; then
            echo -e "${GREEN}更新成功${NC}"
        else
            echo -e "${RED}更新失败。详细信息：${NC}"
            echo "$response"
        fi
    else
        echo -e "${GREEN}当前IP ($answer) 与新IP ($new_ip) 相同，无需更新 $domain${NC}"
    fi
}

function add_dns() {
    local domain=$1
    local new_ip=$2
    if [[ -z "$new_ip" ]]; then
        debug_log "跳过添加空IP记录"
        return
    fi
    echo -e "${YELLOW}正在创建新DNS记录: $domain -> $new_ip${NC}"
    debug_log "发送添加请求到: ${base_url}/control/rewrite/add"
    response=$(curl $CURL_OPTS -v -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Basic ${auth_base64}" \
        -d "{\"domain\": \"$domain\", \"answer\": \"$new_ip\"}" \
        ${base_url}/control/rewrite/add 2>&1)
    debug_log "API响应: $response"
    if [[ $response =~ "200" ]]; then
        echo -e "${GREEN}DNS记录创建成功${NC}"
    else
        echo -e "${RED}DNS记录创建失败。详细信息：${NC}"
        echo "$response"
        # 启用调试输出以查看完整响应
        curl $CURL_OPTS -v -X POST \
            -H "Content-Type: application/json" \
            -H "Authorization: Basic ${auth_base64}" \
            -d "{\"domain\": \"$domain\", \"answer\": \"$new_ip\"}" \
            ${base_url}/control/rewrite/add
    fi
}

debug_log "获取现有DNS记录列表"
results=$(curl $CURL_OPTS -H "Authorization: Basic ${auth_base64}" ${base_url}/control/rewrite/list) || {
    echo -e "${RED}连接到AdGuard Private服务失败。请检查：${NC}"
    echo -e "1. 服务地址 ${base_url} 是否正确"
    echo -e "2. 网络连接是否正常"
    echo -e "3. 服务器是否在线"
    exit 1
}

# 验证API返回结果的格式
if ! echo "$results" | jq . >/dev/null 2>&1; then
    echo -e "${RED}API返回的数据格式无效。实际返回：${NC}"
    echo "$results"
    exit 1
fi

debug_log "DNS记录列表响应: $results"

if [[ -z "$results" || "$results" == "null" ]]; then
    echo -e "${RED}获取DNS记录列表失败或返回为空${NC}"
    exit 1
fi

# 检查IPv4和IPv6地址是否获取成功
debug_log "获取到的IPv4地址: $ipv4"
debug_log "获取到的IPv6地址: $ipv6"

if [[ -z "$ipv4" ]]; then
    echo -e "${YELLOW}警告: 未能获取IPv4地址${NC}"
fi

if [[ -z "$ipv6" ]]; then
    echo -e "${YELLOW}警告: 未能获取IPv6地址${NC}"
fi

# 添加标志位来跟踪是否找到了记录
found_ipv4=false
found_ipv6=false

for row in $(echo $results | jq -c '.[]'); do
    domain=$(echo $row | jq -r '.domain')
    debug_log "处理记录: domain=$domain"
    if [[ $domain != $ddns_domain ]]; then
        debug_log "域名不匹配 $ddns_domain, 跳过"
        continue
    fi
    answer=$(echo $row | jq -r '.answer')
    debug_log "记录应答: $answer"
    if [[ $answer == *":"* ]]; then
        found_ipv6=true
        update_dns $domain $answer $ipv6
    else
        found_ipv4=true
        update_dns $domain $answer $ipv4
    fi
done

# 彩色化状态输出
if [[ $found_ipv4 == false && ! -z "$ipv4" ]]; then
    echo -e "${YELLOW}未找到IPv4记录，正在创建...${NC}"
    add_dns $ddns_domain $ipv4
fi

if [[ $found_ipv6 == false && ! -z "$ipv6" ]]; then
    echo -e "${YELLOW}未找到IPv6记录，正在创建...${NC}"
    add_dns $ddns_domain $ipv6
fi
