#!/usr/bin/env bash

# Proxy parameters utility functions and constants
readonly PROXY_PARAMS=(
    use-proxy
    proxy-type
    proxy-address
    proxy-port
    use-proxy-authorization
    proxy-username
    proxy-password
)

readonly PROXY_PARAMS_DESC=(
    "Use proxy server: 1 or 0"
    "Proxy server type: HTTP, SOCKS4 or SOCKS5"
    "Proxy server hostname or IP address"
    "Proxy server port"
    "Use proxy server authorization: 1 or 0"
    "Proxy server username"
    "Proxy server password"
)

readonly PROXY_PARAMS_DESC_LONG=(
    ""
    ""
    ""
    ""
    ""
    ""
    ""
)

readonly PROXY_PARAMS_IMPLICIT_DEFAULTS=(
    "0"
    ""
    ""
    ""
    "0"
    ""
    ""
)

validateUseProxyParam()
{
    echo -n "$1" | grep -E '^(0|1)$' >/dev/null 2>&1
}
validateProxyTypeParam()
{
    echo -n "$1" | grep -E '^(HTTP|SOCKS4|SOCKS5)$' >/dev/null 2>&1
}
validateProxyAddressParam()
{
    test -n "$1"
}
validateProxyPortParam()
{
    echo -n "$1" | grep -E '^[0-9]+$' >/dev/null 2>&1
}
validateUseProxyAuthorizationParam()
{
    echo -n "$1" | grep -E '^(0|1)$' >/dev/null 2>&1
}
validateProxyUsernameParam()
{
    test -n "$1"
}
validateProxyPasswordParam()
{
    test -n "$1"
}

argToConfigParam()
{
    local argName="$1"
    shift 1

    # transform 'aaa-bbb-ccc' to 'AaaBbbCbb'
    echo "$argName" | awk -F- '
    {
        for (i = 1; i <= NF; i++)
        {
            s=$i
            printf "%s", toupper(substr(s, 1, 1))
            printf "%s", tolower(substr(s, 2))
        }
    }'
}

validate_proxy_parameters()
{
    while [ $# -gt 0 ]; do
        local arg="$1"
        shift

        local argName="${arg%%=*}"
        local argValue="${arg#*=}"
        [ -z "$argName" ] && argName="$arg"

        if [ "${argName:0:2}" = '--' ]; then
            local cleanArgName="${argName:2}"

            local found=0
            for i in "${PROXY_PARAMS[@]}"; do
                [ "$i" = "$cleanArgName" ] || continue

                local validateCallback="validate$(argToConfigParam "$cleanArgName")Param"
                if declare -f "$validateCallback" >/dev/null 2>&1; then
                    eval "$validateCallback \"\$argValue\"" || break
                fi

                found=1
                break
            done
            [ $found -eq 1 ] && continue

            echo "Error: Invalid argument: '${arg}'"
            return 1
        fi
    done
}
