#!/bin/bash

OPERATOR_GO_PACKAGE="github.com/syndesisio/syndesis/install/operator"
OPERATOR="syndesis-operator"
OPERATOR_BINARY=$HOME/.syndesis/bin/${OPERATOR}

operatorsdk_is_available() {
    set +e
    which operator-sdk &>/dev/null
    if [ $? -ne 0 ]; then
        set -e
        printf "\nERROR: 'operator-sdk' not installed. This is necessary if generating new operator source code but not essential for compiling the operator.\n\n"
        return
    fi

    set -e
    if [ "$(pwd)" != "$GOPATH/src/${OPERATOR_GO_PACKAGE}" ] ; then
        echo "
ERROR: operator-sdk only works on project's directly in the \$GOPATH. If the intention is to simply compile the operator then this can be ignored.
However, to generate the operator source code then the project must be relocated under the \$GOPATH so that :'$(pwd)'
is located at '$GOPATH/src/${OPERATOR_GO_PACKAGE}'."
        return
    fi

    echo "OK"
}

check_operator_requirements() {
    local hasgo=$(go_is_available)
    local hasdocker=$(docker_is_available)
    local hassdk=$(operatorsdk_is_available)

    # Still possible to build if one or other is available
    if [ "$hasgo" != "OK" ] && [ "$hasdocker" != "OK" ]; then
        printf "ERROR: Cannot build operator since neither 'go' nor 'docker' is available ..... \n\t\t$hasgo\n\t\t$hasdocker\n"
        return
    fi

    echo "OK"
}

# Make sure the binary path exists
prepare_operator_binary_path() {
    local path=$(dirname ${OPERATOR_BINARY})
    if [[ ! -d ${path} ]]; then
        mkdir -p ${path}
    fi
}

# check that a given binary is in $PATH
check_for_command() {
    local cmd=${1:-curl}

    if $(which ${cmd} >/dev/null 2>&1); then
        return 0
    else
        return 1
    fi
}

# check that the operator binary is in place
check_operator_binary() {
    if [[ -x ${OPERATOR_BINARY} ]]; then
        if [[ $(${OPERATOR_BINARY} -h | grep 'syndesis') ]]; then
            return 0
        fi
    fi
    return 1
}

# download the operator binary
download_operator_binary() {
    local pattern=""

    prepare_operator_binary_path
    check_operator_binary && return
    echo "operator binary not found under ${OPERATOR_BINARY}, attempting to download..."

    if ! check_for_command curl; then
        echo "curl is required to download the operator binary, but it wasn't found in the system"
        return 1
    fi

    case "$OSTYPE" in
        darwin*)  pattern="darwin-amd64" ;;
        linux*)   pattern="linux-amd64" ;;
        msys*)    pattern="windows-amd64" ;;  #using mingw64 on windows
        *)        pattern="unknown" ;;
    esac

    if [[ "${pattern}" != "unknown" ]]; then
        release_tag="$(readopt --tag)"
        asset_name="${OPERATOR}-${pattern}"

        local url
        if [[ -n "$release_tag" ]]; then
            url=$(curl -s "https://api.github.com/repos/syndesisio/syndesis/releases/tags/${release_tag}" \
                | jq -r 'select(.tag_name |startswith("2.")|not)| .assets[] | select(.name |startswith("'"${asset_name}"'"))| .browser_download_url' \
                | head -1)
        else
            url=$(curl -s "https://api.github.com/repos/syndesisio/syndesis/releases?per_page=4" \
                | jq -r '.[]| select(.tag_name |startswith("2.")|not)| .assets[] | select(.name |startswith("'"${asset_name}"'"))| .browser_download_url' \
                | head -1)
        fi

        #
        # Check curl returns a valid url
        #
        if [ -z "${url}" ]; then
            if [[ -n "$release_tag" ]]; then
                echo "unable to find a valid release url for release tag ${release_tag}"
            else
                echo "unable to find any valid release urls"
            fi
            return 1
        fi

        if $(curl -sL ${url} | tar xz -C $(dirname ${OPERATOR_BINARY})); then
            chmod +x ${OPERATOR_BINARY}
        else
            echo "unable to download operator from ${url}"
            return 1
        fi

        if $(check_operator_binary); then
            _version=$(echo ${url}| cut -d "/" -f 8)
            echo "syndesis-operator ${_version} binary successfully downloaded"
            return 0
        else
            echo "operator binary download failed. Please try manually downloading from ${url} into $(dirname ${OPERATOR_BINARY})"
            return 1
        fi
    else
        echo "Unknown platform [ ${OSTYPE} ], "
        return 1
    fi
}

print_error_and_exit() {
    echo $1
    exit 1
}
