#!/bin/sh
# shellcheck shell=dash

# A simple script that is run on a remote host to download and install the
# agent binary.

set -u

ROOT_URL=${ROOT_URL:-"https://static.prymn.net/agent/dist"}

main() {
    if [ $# -eq 0 ]; then
        exit_error "missing command parameters. please make sure you copied the installation command correctly."
    fi

    check_user_is_root

    check_os
    local arch=${RETURN_VALUE}

    check_for_command curl
    check_for_command mktemp

    local dir
    dir="$(mktemp -d)"
    local file="${dir}/prymn_agent"
    local url="${ROOT_URL}/${arch}/prymn_agent"

    printf "info: downloading prymn agent...\n" 1>&2

    ensure download "${url}" "${file}"
    ensure chmod u+x "${file}"

    # Run the installer
    "${file}" --install "$@"
    local ret=$?

    rm "${file}"
    rmdir "${dir}"

    return $ret
}

check_user_is_root() {
    if [ "$(id -u)" -ne 0 ]; then
        exit_error "this script must be run as the root user."
    fi
}

check_os() {
    local os_release os_id os_version_id os_pretty os_old_flag
    if test -e /etc/os-release; then
        os_release="/etc/os-release"
    elif test -e /usr/lib/os-release; then
        os_release="/usr/lib/os-release"
    else
        exit_error "could not determine your operating system; it might not be supported."
    fi

    # shellcheck disable=SC1090
    . "${os_release}"

    local os_id=${ID:-0}
    local os_version_id=${VERSION_ID:-0}
    local os_pretty=${PRETTY_NAME:-Linux}

    if [ "${os_id}" = 0 ] || [ "${os_version_id}" = 0 ]; then
        exit_error "could not detect your operating system type or version."
    fi

    case "${os_id}" in
        debian)
            local min_version=10
            if [ "${os_version_id}" -lt ${min_version} ]; then
                warning "detected Debian version ${os_version_id} which may be too old."
            fi
            ;;

        ubuntu)
            local min_version="20.09"
            os_old_flag="$(echo "${os_version_id}" | awk -v n=${min_version} '{print $1 < n}')"
            if [ "${os_old_flag}" -eq 1 ]; then
                warning "detected Ubuntu version ${os_version_id} which may be too old."
            fi
            ;;

        *)
            exit_error "your operating system ${os_pretty} is not be supported."
            ;;
    esac

    local arch clib kernel cputype
    # TODO: check for musl (probably not be needed because we support distros
    # that don't use it)
    clib="gnu"
    kernel="$(uname -s)"
    cputype="$(uname -m)"

    case "${kernel}" in
        Linux)
            arch=unknown-linux-${clib}
            ;;

        *)
            exit_error "your operating system type ${kernel} is not supported."
            ;;
    esac

    case "${cputype}" in
        x86_64 | x64)
            arch="x86_64-${arch}"
            ;;

        aarch64 | arm64)
            arch="aarch64-${arch}"
            ;;

        *)
            exit_error "your CPU architecture ${cputype} is not supported."
            ;;
    esac

    RETURN_VALUE="${arch}"
}

download() {
    local err
    err=$(curl -sSfL "$1" -o "$2" 2>&1)
    if [ -n "$err" ]; then
        exit_error "$err"
    fi
}

warning() {
    printf "warning: %s\n" "$1" >&2
}

exit_error() {
    printf "error: %s\n" "$1" >&2
    exit 1
}

check_for_command() {
    if ! command -v "$1" > /dev/null 2>&1; then
        exit_error "the program '$1' is required, but it was not found in your system."
    fi
}

ensure() {
    "$@" || exit_error "failed to execute: $*"
}

main "$@" || exit 1