#!/bin/sh
#

#############################################################
# AnripDdns v6.2.0
#
# Dynamic DNS using DNSPod API
#
# Author: Rehiy, https://github.com/rehiy
#                https://www.anrip.com/?s=dnspod
# Collaborators: ProfFan, https://github.com/ProfFan
#
# Usage: please refer to `ddnspod.sh`
#
#############################################################

export arToken

# Get 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|FreeBSD)
            hostIp=$(ifconfig | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | grep -Ev "$lanIps")
        ;;
    esac

    if [ -z "$hostIp" ]; then
        return 1
    fi

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

    echo $hostIp

}

# Get IPv6

arWanIp6() {

    local hostIp

    if type curl >/dev/null 2>&1; then
        hostIp=$(curl -s https://v6.ip.sb)
    else
        hostIp=$(wget -q -O- https://v6.ip.sb)
    fi

    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: interface data

arDdnsApi() {

    local agent="AnripDdns/6.2.0(wang@rehiy.com)"

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

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

}

# Fetch Record Id
# Args: domain subdomain recordType

arDdnsLookup() {

    local errMsg

    local recordId

    # Get Record Id
    recordId=$(arDdnsApi "Record.List" "domain=$1&sub_domain=$2&record_type=$3")
    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 "> arDdnsLookup - $errMsg"
        return 1
    fi

    echo $recordId
}

# Update Record Value
# Args: domain subdomain recordId recordType [hostIp]

arDdnsUpdate() {

    local errMsg

    local recordRs
    local recordCd
    local recordIp

    # update ip
    if [ -z "$5" ]; then
        recordRs=$(arDdnsApi "Record.Ddns" "domain=$1&sub_domain=$2&record_id=$3&record_type=$4&record_line=%e9%bb%98%e8%ae%a4")
    else
        recordRs=$(arDdnsApi "Record.Ddns" "domain=$1&sub_domain=$2&record_id=$3&record_type=$4&value=$5&record_line=%e9%bb%98%e8%ae%a4")
    fi

    # parse result
    recordCd=$(echo $recordRs | sed 's/.*{"code":"\([0-9]*\)".*/\1/')
    recordIp=$(echo $recordRs | sed 's/.*,"value":"\([0-9a-fA-F\.\:]*\)".*/\1/')

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

}

# DDNS Check
# Args: domain subdomain [6|4]

arDdnsCheck() {

    local hostIp

    local recordId
    local recordType

    echo "=== Check $2.$1 ==="
    echo "Fetching Host Ip"

    if [ "$3" = "6" ]; then
        recordType=AAAA
        hostIp=$(arWanIp6)
        if [ $? -ne 0 ]; then
            echo $hostIp
            return 1
        else
            echo "> Host Ip: $hostIp"
            echo "> Record Type: $recordType"
        fi
    else
        recordType=A
        hostIp=$(arWanIp4)
        if [ $? -ne 0 ]; then
            echo "> Host Ip: Auto"
            echo "> Record Type: $recordType"
        else
            echo "> Host Ip: $hostIp"
            echo "> Record Type: $recordType"
        fi
    fi

    echo "Fetching RecordId"
    recordId=$(arDdnsLookup "$1" "$2" "$recordType")

    if [ $? -ne 0 ]; then
        echo $recordId
        return 1
    else
        echo "> Record Id: $recordId"
    fi

    echo "Updating Record value"
    arDdnsUpdate "$1" "$2" "$recordId" "$recordType" "$hostIp"

}
