#!/usr/bin/env bash

set -u

readonly APT_KEYRING_URL='https://packages.synapseq.org/apt/keyrings/synapseq-archive-keyring.gpg'
readonly APT_KEYRING_PATH='/usr/share/keyrings/synapseq-archive-keyring.gpg'
readonly APT_SOURCE_PATH='/etc/apt/sources.list.d/synapseq.list'
readonly RPM_GPG_KEY_URL='https://packages.synapseq.org/rpm/RPM-GPG-KEY-synapseq'
readonly RPM_REPO_PATH='/etc/yum.repos.d/synapseq.repo'
readonly RPM_FUSION_URL='https://rpmfusion.org/Configuration'
readonly GITHUB_RELEASES_URL='https://github.com/synapseq-foundation/synapseq/releases'

keyring_tmp=''

if [[ -t 1 ]]; then
	readonly RESET=$'\033[0m'
	readonly BLUE=$'\033[1;34m'
	readonly GREEN=$'\033[1;32m'
	readonly YELLOW=$'\033[1;33m'
	readonly RED=$'\033[1;31m'
else
	readonly RESET=''
	readonly BLUE=''
	readonly GREEN=''
	readonly YELLOW=''
	readonly RED=''
fi

info() {
	printf '%b==> %s%b\n' "$BLUE" "$1" "$RESET"
}

success() {
	printf '%b==> %s%b\n' "$GREEN" "$1" "$RESET"
}

warning() {
	printf '%bWarning: %s%b\n' "$YELLOW" "$1" "$RESET"
}

error() {
	printf '%bError: %s%b\n' "$RED" "$1" "$RESET" >&2
}

abort() {
	error "$1"
	exit 1
}

cleanup() {
	[[ -n $keyring_tmp ]] && rm -f "$keyring_tmp"
}

trap cleanup EXIT

if [[ ${EUID} -ne 0 ]]; then
	abort 'This installer must be run as root. Run: curl --fail --silent --show-error --location https://synapseq.org/install.sh | sudo bash'
fi

if [[ ! -r /dev/tty ]]; then
	abort 'An interactive terminal is required to confirm the installation.'
fi

printf '%bSynapSeq repository installer%b\n' "$GREEN" "$RESET" >/dev/tty
printf 'Do you want to configure the SynapSeq repository and install SynapSeq? [y/N] ' >/dev/tty
IFS= read -r confirmation </dev/tty || abort 'Installation cancelled.'

if [[ $confirmation != 'y' && $confirmation != 'Y' ]]; then
	warning 'Installation cancelled.'
	exit 0
fi

[[ -r /etc/os-release ]] || abort "Unable to identify this Linux distribution. Download the generic Linux release from $GITHUB_RELEASES_URL or open an issue."

# shellcheck disable=SC1091
source /etc/os-release

distribution='unsupported'
if [[ ${ID:-} == 'fedora' ]]; then
	distribution='fedora'
elif [[ " ${ID:-} ${ID_LIKE:-} " == *' debian '* || " ${ID:-} ${ID_LIKE:-} " == *' ubuntu '* ]]; then
	distribution='debian'
fi

install_debian() {
	command -v curl >/dev/null 2>&1 || abort 'curl is required to configure the SynapSeq repository.'

	keyring_tmp=$(mktemp) || abort 'Unable to create a temporary file for the repository key.'

	info 'Downloading the SynapSeq repository key...'
	curl --fail --silent --show-error --location "$APT_KEYRING_URL" --output "$keyring_tmp" || abort 'Unable to download the SynapSeq repository key.'
	install --mode 0644 "$keyring_tmp" "$APT_KEYRING_PATH" || abort 'Unable to install the SynapSeq repository key.'

	info 'Configuring the SynapSeq APT repository...'
	printf '%s\n' "deb [signed-by=$APT_KEYRING_PATH] https://packages.synapseq.org/apt stable main" >"$APT_SOURCE_PATH" || abort 'Unable to configure the SynapSeq APT repository.'

	info 'Updating package information...'
	apt-get update -qq >/dev/null 2>&1 || abort 'Unable to update package information.'

	info 'Installing SynapSeq...'
	DEBIAN_FRONTEND=noninteractive apt-get install --yes --quiet synapseq >/dev/null 2>&1 || abort 'Unable to install SynapSeq.'
	rm -f "$keyring_tmp"
	keyring_tmp=''
}

rpm_fusion_ready() {
	rpm -q rpmfusion-free-release rpmfusion-nonfree-release >/dev/null 2>&1 &&
		dnf --quiet repolist --enabled rpmfusion-free rpmfusion-nonfree >/dev/null 2>&1
}

install_fedora() {
	command -v dnf >/dev/null 2>&1 || abort 'dnf is required to install SynapSeq on Fedora.'

	if ! rpm_fusion_ready; then
		abort "RPM Fusion Free and Nonfree must be configured and enabled before installing SynapSeq. Configure RPM Fusion first: $RPM_FUSION_URL"
	fi

	info 'Importing the SynapSeq repository key...'
	rpm --import "$RPM_GPG_KEY_URL" || abort 'Unable to import the SynapSeq repository key.'

	info 'Configuring the SynapSeq DNF repository...'
	cat >"$RPM_REPO_PATH" <<'EOF'
[synapseq]
name=SynapSeq
baseurl=https://packages.synapseq.org/rpm/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.synapseq.org/rpm/RPM-GPG-KEY-synapseq
EOF

	info 'Refreshing package information...'
	dnf --quiet clean all >/dev/null 2>&1 || abort 'Unable to clear the package cache.'
	dnf --quiet makecache --refresh >/dev/null 2>&1 || abort 'Unable to refresh package information.'

	info 'Installing SynapSeq...'
	dnf --assumeyes --quiet install synapseq >/dev/null 2>&1 || abort 'Unable to install SynapSeq.'
}

case $distribution in
	debian)
		info 'Detected a Debian or Ubuntu based distribution.'
		install_debian
		;;
	fedora)
		info 'Detected Fedora.'
		install_fedora
		;;
	*)
		abort "This Linux distribution is not supported by the remote installer. Download the generic Linux release from $GITHUB_RELEASES_URL or open an issue."
		;;
esac

success 'SynapSeq has been installed successfully.'
