#!/bin/bash
SOURCE="$0"
source /usr/lib/elive-tools/functions
#EL_REPORTS="1"
#el_make_environment

# Function to get IPv6 from a URL
get_ipv6_from_url() {
    local url="$1"
    local ipv6="$(curl -Ls -m 8 -6 "$url" )"
    if [[ $ipv6 =~ ^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$ ]] ; then
        echo "$ipv6"
        return 0
    fi
    return 1
}


#===  FUNCTION  ================================================================
#          NAME:  verify_ip_validity
#   DESCRIPTION:  verify if the obtained ip is correct or not
#    PARAMETERS:  ip value
#       RETURNS:  0 if true, 1 if false
#===============================================================================
verify_ip_validity(){
    ((is_valid_ip)) && return 0
    [[ -z "$ip" ]] && return 1

    el_debug "verifying ip validity: $ip"

    if [[ -z "$ip" ]] || [[ "$ip" = "192.168."* ]] || [[ "$ip" = "127.0.0."* ]] || [[ "$ip" = "10."* ]] ; then
        return 1
    fi

    if ! echo "$ip" | grep -qsE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ; then
        return 1
    fi

    if dpkg --compare-versions "$ip" ge "172.16" && dpkg --compare-versions "$ip" le "172.32" ; then
        return 1
    fi

    is_valid_ip=1
}

main(){

    for arg in "$@"
    do
        case "$arg" in
            "--ipv6"|"--ip6")
                is_ipv6=1
                ;;
        esac
    done

    if ! el_dependencies_check curl ; then
        if ! el_dependencies_install curl ; then
            exit 1
        fi
    fi

    if ! el_verify_internet ; then
        el_error "no internet connection found"
        exit 1
    fi

    if ((is_ipv6)) ; then
        urls_v6=(
            "https://icanhazip.com"
            "https://api64.ipify.org"
            "https://api6.ipify.org"
            "https://ipv6.icanhazip.com"
            "https://v6.ident.me"
            "https://ipv6.wtfismyip.com/text"
        )

        # Try each URL
        for url in "${urls_v6[@]}"; do
            el_debug "Trying $url..."
            ipv6="$(get_ipv6_from_url "$url" )"
            if [ $? -eq 0 ]; then
                echo "$ipv6"
                exit 0
            fi
        done

        ipv6="$( curl -Ls --max-time 14 http://ip6only.me/api/ 2>/dev/null | tr ',' '\n' | grep ":.*:.*:.*:" | sort -u | tail -1 )"

        if echo "$ipv6" | grep -qs ":.*:.*:.*:" ; then
            echo "$ipv6"
            exit 0
            #else
            #ipv6="$( curl -Ls http://ip6only.me/api/ | tr ',' '\n' | grep ":.*:.*:.*:" )"
        fi
    fi



    # superfastest one (requires dnsutils)
    #if [[ -x "$(which dig)" ]] ; then
        #ip="$( dig +short myip.opendns.com @resolver1.opendns.com | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -1 )"
        #read -r ip <<< "$ip"
    #fi


    # note: if you are using ipv6 it will return ipv6
    if ! verify_ip_validity ; then
        el_debug "Trying icanhazip.com ..."
        ip="$( curl -L -A "Mozilla" --max-time 14 -4 -s http://icanhazip.com | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -1 )"
        read -r ip <<< "$ip"
    fi


    # check and try from another if is wrong
    if ! verify_ip_validity ; then
        el_debug "Trying hostip.info ..."
        ip="$( curl -L -A "Mozilla" --max-time 14 -4 -s http://www.hostip.info | grep -i "IP address:.*" | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sed -e 's|^.*address:  <b>||g' -e 's|</b>.*$||g' -e 's|^.*<b>||g' | tail -1 )"
        read -r ip <<< "$ip"
    fi

    # check and try from another if is wrong
    # update: working one ipv4 based one
    if ! verify_ip_validity ; then
        el_debug "Trying showmyip.co.uk ..."
        ip="$( curl -L -A "Mozilla" --max-time 14 -4 -s http://www.showmyip.co.uk | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sed -e 's|^.*address:  <b>||g' -e 's|</b>.*$||g' -e 's|^.*<b>||g' | tail -1 )"
        if [[ -z "$ip" ]] ; then
            el_debug "Trying showmyip.com ..."
            ip="$( lynx -dump https://www.showmyip.com/ | grep "Your IPv4" | sed -e 's|^.*IPv4 ||g' )"
        fi
        read -r ip <<< "$ip"
    fi


    # fastest one
    # note: should not include httpS and not user-agent (should be curl?)
    # note: if you are using ipv6 it will return ipv6
    if ! verify_ip_validity ; then
        el_debug "Trying ipecho.net ..."
        ip="$( curl -L --max-time 14 -4 -s http://ipecho.net/plain | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | tail -1 )"
        read -r ip <<< "$ip"
    fi




    if ! verify_ip_validity ; then
        el_error "Not correct external IP get: '$ip'"
        exit 1
    else
        echo "$ip"
    fi

}

#
#  MAIN
#
main "$@"

# vim: set foldmethod=marker :
