#!/bin/sh
#
# This script is used to automate getting MOFED releases without having to
# interact with the Javascript downloader available at:
# https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/
#
# It was reverse-engineered and may break upon upstream changes.
#
# The upstream server can take up to 10 seconds to serve some requests, so they
# should be used sparsely and intermediate results should be cached.
#
# Example usage: ./upstream.sh download 24.04-0.7.0.0

set -eu

DEFAULT_DISTRO='Ubuntu'
DEFAULT_OS='Ubuntu 23.04'
DEFAULT_ARCH='x86_64'

# Functions to interact with the downloader

post() {
	data="$1"
	info "Querying API, this may take some time"
	curl 'https://downloaders.azurewebsites.net/downloaders/mlnx_ofed_downloader/helper.php' \
		-X POST \
		--silent \
		--data-raw "$data"
}

get_versions() {
	post 'action=get_versions'
}

get_distros() {
	version="$1"
	post "action=get_distros&version=$version"
}

get_oses() {
	version="$1"
	distro="$2"
	post "action=get_oses&version=$version&distro=$distro"
}

get_arches() {
	version="$1"
	distro="$2"
	os="$3"
	post "action=get_arches&version=$version&distro=$distro&os=$os"
}

get_download_info() {
	version="$1"
	distro="$2"
	os="$3"
	arch="$4"
	post "action=get_download_info&version=$version&distro=$distro&os=$os&arch=$arch"
}

# Actions

action_versions() {
	get_versions | jq -r '.versions | .[]' | sort -n
}

action_major_versions() {
	get_versions | jq -r '.versions | .[]' | cut -d'-' -f1 | sort -n | uniq
}

action_ga_versions() {
	get_versions | jq -r '.ga | .[]'
}

action_distros() {
	version="$1"
	get_distros "$version" | jq -r '.[]'
}

action_oses() {
	version="$1"
	distro="$2"
	get_oses "$version" "$distro" | jq -r '.[]'
}

action_arches() {
	version="$1"
	distro="$2"
	os="$3"
	get_arches "$version" "$distro" "$os" | jq -r '.[]'
}

action_download() {
	version="$1"
	distro="$DEFAULT_DISTRO"
	os="$DEFAULT_OS"
	arch="$DEFAULT_ARCH"

	if [ $# -gt 1 ]
	then
		distro="$2"
	fi
	if [ $# -gt 2 ]
	then
		os="$3"
	fi
	if [ $# -gt 3 ]
	then
		arch="$4"
	fi

	info=$(get_download_info "$version" "$distro" "$os" "$arch")
	file=$(echo "$info" | jq -r '.files[] | select(.desc == "SOURCES")')
	url=$(echo "$file" | jq -r '.url')
	sha=$(echo "$file" | jq -r '.sha')
	dest=$(echo "$file" | jq -r '.file')

	info "Downloading $dest from $url"

	# www.mellanox.com links may redirect to content.mellanox.com, be sure
	# to follow redirects
	curl -L "$url" --output "$dest"

	# Upstream provides checksum, check it
	info "Verifying sha256sum"
	echo "$sha $dest" | sha256sum --check --status \
		|| die "sha256sum check failed"


	info "Done"
	# Print the name of the downloaded file for other scripts to take over
	echo "$dest"
}

action_help() {
	usage
}

# Utils

die() {
	echo >&2 "ERROR:" "$@"
	exit 2
}

info() {
	echo >&2 "INFO:" "$@"
}

usage() {
	cat >&2 <<EOF
Usage: $0 ACTION [ARG]...

List of supported actions:

	versions                               -- List available versions.
	major_versions                         -- List available major versions.
	ga_versions                            -- List available GA versions.

	distros VERSION                        -- List supported distributions.
	oses VERSION DISTRO                    -- List supported OSes.
	arches VERSION DISTRO OS               -- List supported architectures.

	download VERSION [DISTRO] [OS] [ARCH]  -- Download source release.

	help                                   -- Display this message and exit.

EOF
	exit 1
}

# Main

if [ "$#" -lt 1 ]
then
	usage
fi

action="$1"
shift

"action_$action" "$@"
