#!/usr/bin/env bash
set -euxo pipefail

# Set the version of rust to install
RUST_VERSION="1.84.0"
# Set the platform of our machine (the one we are running this script on)
HOST_TARGET="x86_64-unknown-linux-gnu"

tmp=$(mktemp -d)
export GNUPGHOME="$tmp"

# Delete if present and (re)download the file `$1` from URL `$2` via `curl`
download() {
    local file=$1
    local url=$2
    rm -rf "${file}"
    curl --retry 3 -o "${file}" "${url}"
}

# Download the file `$1` and it's signature from the Rust distrubution
download_with_signature() {
    local file=$1
    local file_url="https://static.rust-lang.org/dist/${file}"
    local signature="${file}.asc"
    local signature_url="https://static.rust-lang.org/dist/${signature}"

    download "${signature}" "${signature_url}"
    download "${file}" "${file_url}"
}

# Verify the file `$1` with the signature `$2` using GPG
verify() {
    local file=$1
    local signature=$2
    if ! gpgv --homedir "${tmp}" --keyring "${tmp}/pubring.kbx" "${signature}" "${file}"; then
        echo "Signature verification failed for ${file}!"
        exit 2
    fi
}


# Import the Rust singing key to verify the rust packages we will download
# Note: available from https://static.rust-lang.org/rust-key.gpg.ascii and https://keybase.io/rust
gpg --import <<EOF
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1

[encoded data, 5200 characters]
Mve696B5tlHyc1KxjHR6w9GRsh4=
=5FXw
-----END PGP PUBLIC KEY BLOCK-----
EOF
KEY_FINGERPRINT="108F66205EAEB0AAA8DD5E1C85AB96E6FA1BE5FE"

# Verify fingerprint
if ! gpg --homedir "${tmp}" --no-default-keyring --keyring "${tmp}/pubring.kbx" --list-keys "${KEY_FINGERPRINT}"; then
    echo "Wrong fingerprint on imported public key!"
fi

# Download the Rust installer with the target for the host machine
# verifying it using the Rust signing key
RUST_INSTALLER=rust-${RUST_VERSION}-${HOST_TARGET}.tar.gz
RUST_INSTALLER_SIGNATURE="${RUST_INSTALLER}.asc"
download_with_signature "${RUST_INSTALLER}"
verify "${RUST_INSTALLER}" "${RUST_INSTALLER_SIGNATURE}"

# Download and verify the Rust TOML for our compiler
RUST_TOML="channel-rust-${RUST_VERSION}.toml"
RUST_TOML_SIGNATURE="${RUST_TOML}.asc"
download_with_signature "${RUST_TOML}"
verify "${RUST_TOML}" "${RUST_TOML_SIGNATURE}"

# The additional targets we want for cross-compilation
targets=(
    "pkg.rust-std.target.aarch64-linux-android"
    "pkg.rust-std.target.armv7-linux-androideabi"
    "pkg.rust-std.target.i686-linux-android"
    "pkg.rust-std.target.x86_64-linux-android"
    "pkg.rust-std.target.wasm32-unknown-unknown"
)
# Keep track of the downloaded installers so we can extract and run them later
target_filenames=("${RUST_INSTALLER}")
# Download the additional targets for cross-compilation
# and verify them using the hashes
for target in "${targets[@]}"
do
    # Parse the url, filename and hash of the target installer from the Rust TOML
    url=$(grep -A 2 -F "${target}" ${RUST_TOML} | sed -n 3p | awk -F' = ' '{print $2}' | sed 's/\"//g')
    filename=$(echo "${url}" | awk -F'/' '{print $NF}')
    hash=$(grep -A 3 -F "${target}" ${RUST_TOML} | sed -n 4p | awk -F' = ' '{print $2}' | sed 's/\"//g')
    # Download and verify the target installer using the extracted data from the Rust TOML
    download "${filename}" "${url}"
    if ! echo "${hash} ${filename}" | sha256sum -c; then
        echo "Checksum verification failed!"
        exit 3
    fi

    target_filenames+=("${filename}")
done


# Extract and run the installers for all the targets (including host) we downloaded
EXTRACT_TMP="installers"
rm -rf "${EXTRACT_TMP}"
mkdir -p "${EXTRACT_TMP}"
for target_file in "${target_filenames[@]}"
do
    tar zxf "${target_file}" -C "${EXTRACT_TMP}"
    extracted_folder=$(echo "${target_file}" | awk -F'.tar' '{print $1}')
    pushd "${EXTRACT_TMP}/${extracted_folder}"
       ./install.sh
    popd
done
