#!/bin/sh
#
# Import ardnspod functions
# ./ardnspod
# Combine your token ID and token together as follows
arToken="tokenid,tokensec"

# Place each domain you want to check as follows
# you can have multiple arDdnsCheck blocks



# IPv6:
# arDdnsCheck "test.org" "subdomain6" 6


# Get WAN IPv4

arWanIp4() {

    local hostIp

    local lanIps="^$"

    lanIps="$lanIps|(^10\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)"
    lanIps="$lanIps|(^127\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$)"
    lanIps="$lanIps|(^169\.254\.[0-9]{1,3}\.[0-9]{1,3}$)"
    lanIps="$lanIps|(^172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3}$)"
    lanIps="$lanIps|(^192\.168\.[0-9]{1,3}\.[0-9]{1,3}$)"

    case $(uname) in
        'Linux')
            hostIp=$(ip -o -4 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1 | grep -Ev "$lanIps")
        ;;
        'Darwin')
            hostIp=$(ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | grep -Ev "$lanIps")
        ;;
    esac

    if [ -z "$hostIp" ]; then
        if type wget >/dev/null 2>&1; then
            hostIp=$(wget -q -O- http://members.3322.org/dyndns/getip)
        else
            hostIp=$(curl -s http://members.3322.org/dyndns/getip)
        fi
    fi

    if [ -z "$hostIp" ]; then
        echo "arWanIp4 - Can't get ip address"
        return 1
    fi

    if [ -z "$(echo $hostIp | grep -E '^[0-9\.]+$')" ]; then
        echo "arWanIp4 - Invalid ip address $hostIp"
        return 1
    fi

    echo $hostIp

}

# Get WAN IPv6

arWanIp6() {

    local hostIp

    local lanIps="(^$)|(^::1$)|(^fe[8-9,A-F])"

    case $(uname) in
        'Linux')
            hostIp=$(ip -o -6 addr list | grep -Ev '\s(docker|lo)' | awk '{print $4}' | cut -d/ -f1 | grep -Ev "$lanIps" | tail -n 1)
        ;;
        'Darwin')
            hostIp=$(ifconfig | grep "inet6 " | awk '{print $2}' | grep -Ev "$lanIps" | tail -n 1)
        ;;
    esac

    if [ -z "$hostIp" ]; then
        echo "arWanIp6 - Can't get ip address"
        return 1
    fi

    if [ -z "$(echo $hostIp | grep -E '^[0-9a-fA-F:]+$')" ]; then
        echo "arWanIp6 - Invalid ip address"
        return 1
    fi

    echo $hostIp

}

# Dnspod Bridge
# Args: type data

arDdnsApi() {

    local agent="AnripDdns/6.1.0(mail@anrip.com)"

    local apiurl="https://dnsapi.cn/${1:?'Info.Version'}"
    local params="login_token=$arToken&format=json&$2"

    if type wget >/dev/null 2>&1; then
        wget -q -O- --no-check-certificate -U $agent --post-data $params $apiurl
    else
        curl -s -A $agent -d $params $apiurl
    fi

}

# Fetch Ids of Domain and Record
# Args: recordType domain subdomain

arDdnsIds() {

    local errMsg

    local domainId
    local recordId

    # Get Domain Id
    domainId=$(arDdnsApi "Domain.Info" "domain=$2")
    domainId=$(echo $domainId | sed 's/.*"id":"\([0-9]*\)".*/\1/')

    if ! [ "$domainId" -gt 0 ] 2>/dev/null ;then
        errMsg=$(echo $domainId | sed 's/.*"message":"\([^\"]*\)".*/\1/')
        echo "arDdnsIds - $errMsg"
        return 1
    fi

    # Get Record Id
    recordId=$(arDdnsApi "Record.List" "domain_id=$domainId&sub_domain=$3&record_type=$1")
    recordId=$(echo $recordId | sed 's/.*"id":"\([0-9]*\)".*/\1/')

    if ! [ "$recordId" -gt 0 ] 2>/dev/null ;then
        errMsg=$(echo $recordId | sed 's/.*"message":"\([^\"]*\)".*/\1/')
        echo "arDdnsIds - $errMsg"
        return 1
    fi

    echo $domainId $recordId
}

# Fetch Record Ip
# Args: domainId recordId

arDdnsRecordIp() {

    local errMsg

    local recordIp

    # Get Record Ip
    recordIp=$(arDdnsApi "Record.Info" "domain_id=$1&record_id=$2")
    recordIp=$(echo $recordIp | sed 's/.*,"value":"\([0-9a-fA-F\.\:]*\)".*/\1/')

    # Output Record Ip
    case "$recordIp" in
        [1-9]*)
            echo $recordIp
            return 0
        ;;
        *)
            errMsg=$(echo $recordIp | sed 's/.*"message":"\([^\"]*\)".*/\1/')
            echo "arDdnsRecordIp - $errMsg"
            return 1
        ;;
    esac

}

# Update Record Ip
# Args: domainId recordId subdomain hostIp recordType

arDdnsUpdate() {

    local errMsg

    local recordRs
    local recordIp
    local recordCd

    if [ -z "$5" ]; then
        echo "arDdnsUpdate - Args number error"
        return 1
    fi

    # Update Ip
    recordRs=$(arDdnsApi "Record.Modify" "domain_id=$1&record_id=$2&sub_domain=$3&record_type=$5&value=$4&record_line=%e9%bb%98%e8%ae%a4")
    recordIp=$(echo $recordRs | sed 's/.*,"value":"\([0-9a-fA-F\.\:]*\)".*/\1/')
    recordCd=$(echo $recordRs | sed 's/.*{"code":"\([0-9]*\)".*/\1/')

    # Output Result
    if [ "$recordIp" == "$4" ] && [ "$recordCd" == "1" ]; then
        echo "arDdnsUpdate - success"
        return 0
    else
        errMsg=$(echo $recordRs | sed 's/.*,"message":"\([^"]*\)".*/\1/')
        echo "arDdnsUpdate - $errMsg"
        return 1
    fi

}

# DDNS Check
# Args: Main Sub
arDdnsCheck() {

    local errCode

    local recordType
    local hostIp

    local ddnsIds
    local lastIp
    local postRs

    echo "Fetching Host Ip"
    if [ "$3" == "6" ]; then
        recordType=AAAA
        hostIp=$(arWanIp6)
    else
        recordType=A
        hostIp=$(arWanIp4)
    fi

    errCode=$?
    echo "> Host Ip: $hostIp"
    echo "> Record Type: $recordType"
    if [ $errCode -ne 0 ]; then
        return 1
    fi

    echo "Fetching Ids of $2.$1"
    ddnsIds=$(arDdnsIds $recordType $1 $2)

    errCode=$?
    echo "> Domain Ids: $ddnsIds"
    if [ $errCode -ne 0 ]; then
        return 1
    fi

    echo "Checking Record for $2.$1"
    lastIp=$(arDdnsRecordIp $ddnsIds)

    errCode=$?
    echo "> Last Ip: $lastIp"
    if [ $errCode -ne 0 ]; then
        return 1
    fi

    if [ "$lastIp" == "$hostIp" ]; then
        echo "> Last Ip is the same as host Ip"
        return 0
    fi

    echo "Updating Record for $2.$1"
    postRs=$(arDdnsUpdate $ddnsIds $2 $hostIp $recordType)

    errCode=$?
    echo "> $postRs"
    if [ $errCode -ne 0 ]; then
        return 1
    fi

}


# IPv4:
arDdnsCheck "根域名" "二级域名前缀"