#!/bin/bash

SCRIPT_NAME="${0##*/}"
readonly SCRIPT_NAME

check_deps() {
    command -v curl >/dev/null 2>&1 || die "curl: command not found"
}

usage() {
    cat <<EOF
Usage: ${SCRIPT_NAME} [--family auto|4|6] [-h|--help]

Query an external service using curl and print:
  1) public IP address
  2) reverse DNS (PTR record)
  3) curl version

Options:
  --family auto|4|6   select IP protocol version (default: auto)
  -h, --help          show help and exit
EOF
}

shell_quote() {
    local -r string="$1"
    printf "'%s'" "${string//'/'\\''/}"
}

die() {
    local -r message="$1"
    printf "%s: %b\n" "${SCRIPT_NAME}" "${message}" >&2
    exit 1
}

invalid_option() {
    local -r option="$1"
    die "invalid option $(shell_quote "${option}")
Try '${SCRIPT_NAME} --help' for usage."
}

parse_args() {
    family="auto"
    while (($# > 0)); do
        case "$1" in
        -h | --help)
            usage
            exit 0
            ;;
        --family)
            ( (($# < 2)) || [[ -z "$2" ]]) &&
                die "--family requires an argument (auto, 4 or 6)"
            family="$2"
            shift 2
            ;;
        --family=*)
            family="${1#*=}"
            [[ -z "${family}" ]] &&
                die "--family requires an argument (auto, 4 or 6)"
            shift
            ;;
        *) invalid_option "$1" ;;
        esac
    done
    validate_args
}

validate_args() {
    case "${family}" in
    auto | 4 | 6) ;;
    *) die "invalid value for family: '${family}' (expected auto, 4 or 6)" ;;
    esac
}

show_ip() {
    local -a curl_args=()
    [[ ${family} == "4" ]] && curl_args=("-4")
    [[ ${family} == "6" ]] && curl_args=("-6")
    curl "${curl_args[@]}" zx2c4.com/ip
}

main() {
    check_deps
    parse_args "$@"
    show_ip
}

main "$@"
