#!/bin/sh

NAME=tencentddns
log_file=/var/log/$NAME.log

uci_get_by_name() {
	local ret=$(uci get $NAME.$1.$2 2>/dev/null)
	echo ${ret:=$3}
}

uci_bool_by_name() {
	case "$(uci_get_by_name $1 $2)" in
		1|on|true|yes|enabled) return 0;;
	esac
	return 1
}
 
intelnetip() {
	tmp_ip=`curl -sL --connect-timeout 3   ns1.dnspod.net:6666`
	if [ "Z$tmp_ip" == "Z" ]; then
		tmp_ip=`curl -sL --connect-timeout 3 members.3322.org/dyndns/getip`
	fi
	if [ "Z$tmp_ip" == "Z" ]; then
		tmp_ip=`curl -sL --connect-timeout 3 14.215.150.17:6666`
	fi
	if [ "Z$tmp_ip" == "Z" ]; then
		tmp_ip=`curl -sL --connect-timeout 3 whatismyip.akamai.com`
	fi
	echo -n $tmp_ip
}

resolve2ip() {
	# resolve2ip domain<string>
	domain=$1
	tmp_ip=`nslookup    $domain f1g1ns1.dnspod.net 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
	if [ "Z$tmp_ip" == "Z" ]; then
		tmp_ip=`nslookup $domain f1g1ns2.dnspod.net  2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
	fi
	if [ "Z$tmp_ip" == "Z" ]; then
		tmp_ip=`nslookup $domain 114.114.115.115 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -n1`
	fi
	if [ "Z$tmp_ip" == "Z" ]; then
		tmp_ip=`curl -sL --connect-timeout 3 "119.29.29.29/d?dn=$domain"`
	fi
	echo -n $tmp_ip
}

resolve2ipv6() {
	# resolve2ip domain<string>
	domain=$1
	tmp_ip=`nslookup    $domain f1g1ns1.dnspod.net 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-z]{1,4}:[0-z]{1,4}:[0-z]{1,4}:[0-z]{1,4}::[1]' | tail -n1`
	if [ "Z$tmp_ip" == "Z" ]; then
		tmp_ip=`nslookup $domain f1g1ns2.dnspod.net  2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-z]{1,4}:[0-z]{1,4}:[0-z]{1,4}:[0-z]{1,4}::[1]' | tail -n1`
	fi
	if [ "Z$tmp_ip" == "Z" ]; then
		tmp_ip=`nslookup $domain 114.114.115.115 2>/dev/null | sed '/^Server/d; /#53$/d' | grep -oE '[0-z]{1,4}:[0-z]{1,4}:[0-z]{1,4}:[0-z]{1,4}::[1]' | tail -n1`
	fi
	if [ "Z$tmp_ip" == "Z" ]; then
		tmp_ip=`curl -sL --connect-timeout 3 "119.29.29.29/d?dn=$domain"`
	fi
	echo -n $tmp_ip
}

check_tencentddns() {
	echo "$DATE WAN-IP: ${ip}"
	if [ "Z$ip" == "Z" ]; then
		echo "$DATE ERROR, cant get WAN-IP..."
		return 0
	fi
	current_ip=$(resolve2ip "$sub_dm.$main_dm")
	if [ "Z$current_ip" == "Z" ]; then
		rrid='' # NO Resolve IP Means new Record_ID
	fi
	echo "$DATE DOMAIN-IP: ${current_ip}"
	if [ "Z$ip" == "Z$current_ip" ]; then
		echo "$DATE IP dont need UPDATE..."
		return 0
	else
		echo "$DATE UPDATING..."
		return 1
	fi
}

check_tencentddnsv6() {
	echo "$DATE WAN-IP: ${ip}"
	if [ "Z$ip" == "Z" ]; then
		echo "$DATE ERROR, cant get WAN-IP..."
		return 0
	fi
	current_ip=$(resolve2ipv6 "$sub_dm.$main_dm")
	if [ "Z$current_ip" == "Z" ]; then
		rrid='' # NO Resolve IP Means new Record_ID
	fi
	echo "$DATE DOMAIN-IP: ${current_ip}"
	if [ "Z$ip" == "Z$current_ip" ]; then
		echo "$DATE IP dont need UPDATE..."
		return 0
	else
		echo "$DATE UPDATING..."
		return 1
	fi
}

urlencode() {
	# urlencode url<string>
	out=''
	for c in $(echo -n $1 | sed 's/[^\n]/&\n/g'); do
		case $c in
			[a-zA-Z0-9._-]) out="$out$c" ;;
			*) out="$out$(printf '%%%02X' "'$c")" ;;
		esac
	done
	echo -n $out
}

send_request() {
        curl -s -X POST https://dnsapi.cn/$1 -d "login_token=$ak_id,$ak_token&format=json&"$2
}

get_recordid() {
        sed 's/"records"/\n/g' | sed -n '2p' | sed 's/ttl/\n/g' | sed -n 's/.*"id[^0-9]*\([0-9]*\).*/\1\n/p' | sort -ru | sed /^$/d
}


get_recordid2() {
        sed 's/"record"/\n/g' | sed -n '2p' |  sed -n 's/.*"id[^0-9]*\([0-9]*\).*/\1\n/p' | sort -ru | sed /^$/d
}

query_recordid() {
        send_request "Record.List" "domain=$main_dm&sub_domain=$sub_dm&record_type=A"
}

query_recordidv6() {
        send_request "Record.List" "domain=$main_dm&sub_domain=$sub_dm&record_type=AAAA"
}

update_record() {
        send_request "Record.Modify" "domain=$main_dm&sub_domain=$sub_dm&record_id=$1&record_type=A&record_line=%e9%bb%98%e8%ae%a4&value=$ip"
}

update_recordv6() {
        send_request "Record.Modify" "domain=$main_dm&sub_domain=$sub_dm&record_id=$1&record_type=AAAA&record_line=%e9%bb%98%e8%ae%a4&value=$ip"
}

add_record() {
        send_request "Record.Create" "domain=$main_dm&sub_domain=$sub_dm&record_type=A&record_line=%e9%bb%98%e8%ae%a4&value=$ip"
}

add_recordv6() {
        send_request "Record.Create" "domain=$main_dm&sub_domain=$sub_dm&record_type=AAAA&record_line=%e9%bb%98%e8%ae%a4&value=$ip"
}

del_record() {
        send_request "Record.Remove" "domain=$main_dm&record_id=$1"
}

do_ddns_record() {
	if uci_bool_by_name base clean ; then
		query_recordid | get_recordid | while read rr; do
			echo "$DATE Clean record $sub_dm.$main_dm: $rr"
			del_record $rr >/dev/null
			timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
		done
		rrid=''
	fi
	if [ "Z$rrid" == "Z" ]; then
		rrid=`query_recordid | get_recordid`
	fi
	if [ "Z$rrid" == "Z" ]; then
		rrid=`add_record | get_recordid2`
		echo "$DATE ADD record $rrid"
	else
		update_record $rrid >/dev/null 2>&1
		echo "$DATE UPDATE record $rrid"
	fi
	if [ "Z$rrid" == "Z" ]; then
		# failed
		echo "$DATE # ERROR, Please Check Config/Time"
	else
		# save rrid
		uci set tencentddns.base.record_id=$rrid
		uci commit tencentddns
		echo "$DATE # UPDATED($ip)"
	fi
}

do_ddns_recordv6() {
	if uci_bool_by_name base clean ; then
		query_recordidv6 | get_recordid | while read rr; do
			echo "$DATE Clean record $sub_dm.$main_dm: $rr"
			del_record $rr >/dev/null
			timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")
		done
		rrid=''
	fi
	if [ "Z$rrid" == "Z" ]; then
		rrid=`query_recordidv6 | get_recordid`
	fi
	if [ "Z$rrid" == "Z" ]; then
		rrid=`add_recordv6 | get_recordid2`
		echo "$DATE ADD record $rrid"
	else
		update_recordv6 $rrid >/dev/null 2>&1
		echo "$DATE UPDATE record $rrid"
	fi
	if [ "Z$rrid" == "Z" ]; then
		# failed
		echo "$DATE # ERROR, Please Check Config/Time"
	else
		# save rrid
		uci set tencentddns.base.record_id=$rrid
		uci commit tencentddns
		echo "$DATE # UPDATED($ip)"
	fi
}

clean_log() {
	if [ $(cat $log_file 2>/dev/null | wc -l) -ge 16 ]; then
		rm -f $log_file && touch $log_file
		echo "$DATE Log Cleaned"
	fi
}

[ -x /usr/bin/openssl -a -x /usr/bin/curl -a -x /bin/sed ] ||
	( echo "Need [ openssl + curl + sed ]" && exit 1 )

ak_id=$(uci_get_by_name   base key_id)
ak_token=$(uci_get_by_name  base key_token)
rrid=$(uci_get_by_name    base record_id)
main_dm=$(uci_get_by_name base main_domain)
sub_dm=$(uci_get_by_name  base sub_domain)
update_ipv6=$(uci_get_by_name  base ipv6)

iface=$(uci_get_by_name   base interface)
if [ "Z$iface" == "Zinternet" -o "Z$iface" == "Z" ]; then
	ip=$(intelnetip)
else
	if [ $update_ipv6 == 1 ]; then
		ip=$(ubus call network.interface.$iface status | grep '"address"' | grep -oE '[0-z]{1,4}:[0-z]{1,4}:[0-z]{1,4}:[0-z]{1,4}::[1]' | head -1)
	else
		ip=$(ubus call network.interface.$iface status | grep '"address"' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | head -1)
	fi
fi

DATE=$(date +'%Y-%m-%d %H:%M:%S')
timestamp=$(date -u "+%Y-%m-%dT%H%%3A%M%%3A%SZ")

clean_log
if [ $update_ipv6 == 1 ]; then
	check_tencentddnsv6 || do_ddns_recordv6
else
	check_tencentddns || do_ddns_record
fi