#
# SPDX-License-Identifier: Apache-2.0
#
# A set of bash utility functions to parse a URL.
# This script was originated by Scott Little
#

url_protocol () {
    local URL="$1"

    if [ "$URL" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    if echo "$URL" | grep -q '[:][/][/]' ;then
        echo "$URL" | sed 's#^\(.*\)://.*$#\1#'
    else
        echo "http"
    fi
    return 0
}

url_login () {
    local URL="$1"

    if [ "$URL" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    echo "$URL" | sed 's#^.*://\([^/]*\)/.*$#\1#'
    return 0
}

url_user () {
    local URL="$1"
    local LOGIN

    if [ "$URL" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    url_login "$URL" | sed -e '/@/! s#.*## ; s#\([^@]*\)@.*#\1#'
    if [ ${PIPESTATUS[0]} -ne 0  ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): url_login failed"
        return 1
    fi

    return 0
}

url_port () {
    local URL="$1"
    local LOGIN

    if [ "$URL" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    url_login "$URL" | sed -e '/:/! s#.*## ; s#[^:]*:\([^:]*\)#\1#'
    if [ ${PIPESTATUS[0]} -ne 0  ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): url_login failed"
        return 1
    fi

    return 0
}

url_server () {
    local URL="$1"
    local LOGIN

    if [ "$URL" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    url_login "$URL" | sed 's#^.*@## ; s#:.*$##'
    if [ ${PIPESTATUS[0]} -ne 0  ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): url_login failed"
        return 1
    fi

    return 0
}

url_path () {
    local URL="$1"

    if [ "$URL" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    echo "$URL" | sed 's#^.*://[^/]*/\(.*\)$#\1#'
    return 0
}

#
# url_path_to_fs_path:
#
# Convert url format path to file system format.
# e.g. replace %20 with ' '.
#
# Note: Does NOT test the output path to ensure there are
#       no illegal file system characters.
#
url_path_to_fs_path () {
    local INPUT_PATH="$1"
    local TEMP

    if [ "$INPUT_PATH" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    # Deviate from URI spec by not substituding '+' with ' '.
    # It would alias '%20' and we need unique mappings.
    # TEMP="${INPUT_PATH//+/ }"

    TEMP="$INPUT_PATH"
    printf '%b' "${TEMP//%/\\x}"
    return 0
}

#
# fs_path_to_url_path:
#
# Convert file system format path to url format.
# e.g. replace ' ' with %20.
#
fs_path_to_url_path () {
    local INPUT_PATH="$1"
    local LENGTH
    local POS
    local CHAR

    if [ "$INPUT_PATH" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    LENGTH="${#INPUT_PATH}"
    for (( POS = 0; POS < LENGTH; POS++ )); do
        CHAR="${1:POS:1}"
        case $CHAR in
            [/a-zA-Z0-9.~_-])
                # Reference https://metacpan.org/pod/URI::Escape
                printf "$CHAR"
                ;;
            *)
                printf '%%%02X' "'$CHAR"
                ;;
        esac
    done

    return 0
}

#
# normalize_path:
#
# 1) replace // with /
# 2) replace /./ with /
# 3) Remove trailing /
# 4) Remove leading ./
#

normalize_path () {
    local INPUT_PATH="$1"

    if [ "$INPUT_PATH" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    echo "$INPUT_PATH" | sed 's#[/]\+#/#g ; s#[/][.][/]#/#g ; s#/$## ; s#^[.]/##'
    return 0
}


#
# repo_url_to_sub_path:
#
repo_url_to_sub_path () {
    local URL="$1"
    local FAMILY=""
    local SERVER=""
    local URL_PATH=""
    local FS_PATH=""

    if [ "$URL" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    # set FAMILY from URL
    echo $URL | grep -q 'debian[.]org' && FAMILY=debian
    echo $URL | grep -q 'mirror[.]csclub[.]uwaterloo[.]ca[/]debian-security' && FAMILY=debian
    echo $URL | grep -q 'centos[.]org' && FAMILY=centos
    echo $URL | grep -q 'fedoraproject[.]org[/]pub[/]epel' && FAMILY=epel

    SERVER=$(url_server "$URL")
    if [ $? -ne 0  ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): url_server '$URL'"
        return 1
    fi

    URL_PATH="$(url_path "$URL")"
    if [ $? -ne 0  ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): url_path '$URL'"
        return 1
    fi

    FS_PATH="$(url_path_to_fs_path "$URL_PATH")"
    if [ $? -ne 0  ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): url_path_to_fs_path '$URL_PATH'"
        return 1
    fi

    FS_PATH="$(normalize_path "$FS_PATH")"
    if [ $? -ne 0  ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): normalize_path '$FS_PATH'"
        return 1
    fi

    normalize_path "./$FAMILY/$SERVER/$FS_PATH"
    if [ $? -ne 0  ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): normalize_path './$FAMILY/$SERVER/$FS_PATH'"
        return 1
    fi

    return 0
}

STX_MIRROR_PROTOCOL="https"
STX_MIRROR_HOST="mirror.starlingx.windriver.com"
STX_MIRROR_PORT="443"
STX_MIRROR_URL_ROOT="mirror"

url_to_stx_mirror_url () {
    local URL="$1"
    local DISTRO="$2"
    local URL_PATH=""
    local FS_PATH=""

    if [ "$URL" == "" ] || [ "$DISTRO" == "" ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): empty argument"
        return 1
    fi

    FS_PATH="$(repo_url_to_sub_path "$URL")"
    if [ $? -ne 0 ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): repo_url_to_sub_path '$URL'"
        return 1
    fi

    URL_PATH=$(fs_path_to_url_path "$FS_PATH")
    if [ $? -ne 0 ]; then
        >&2 echo "Error: $FUNCNAME (${LINENO}): fs_path_to_url_path '$FS_PATH'"
        return 1
    fi

    echo "$STX_MIRROR_PROTOCOL://$STX_MIRROR_HOST:$STX_MIRROR_PORT/$STX_MIRROR_URL_ROOT/$DISTRO/$URL_PATH"
    return 0
}

url_to_host () {
    local URL="${1}"

    # Strip                protocol,          path,         user/pwd,        port
    echo "${URL}" | sed -e 's#^[^:]*://##' -e 's#/.*$##' -e 's#^[^@]*@##' -e 's#:.*$##'
}

host_to_domain () {
    local host="${1}"
    local elements=0

    elements=$(echo "${host}" | sed 's#[^.]##g' |  wc --chars)
    if [ $elements -gt 2 ]; then
        # strip lead element
        echo "${host}" | sed 's#^[^.]*.##'
    else
        echo "${host}"
    fi
}