#!/usr/bin/env sh
#
# Install mde, a full-screen markdown editor for the terminal.
#
#   curl -fsSL https://flushodds.com/mde/install.sh | sh
#
# It works out which build you need, downloads it, checks it against the
# published SHA-256, and then hands over to mde itself to put the binary
# somewhere your shell will find it. Nothing runs as root and nothing outside
# your own account is touched.
#
# Options, as environment variables:
#   MDE_INSTALL_DIR=~/bin     install somewhere other than the usual place
#   MDE_VERSION=1.0.0         install a specific version
#   MDE_SKIP_VERIFY=1         skip the checksum (not advised)
#
# Read before you run, as with anything piped into a shell. This file is served
# from the same place as the binaries, and is short on purpose.

set -eu

# The site moved under /mde when Flushodds Poker Pro took the root. The old
# addresses still redirect here, so a script someone saved a year ago keeps
# working, but new ones should point straight at the real place.
SITE=${MDE_SITE:-https://flushodds.com/mde}
DOWNLOADS="$SITE/downloads"

say() { echo "$1"; }
die() { echo "install.sh: $1" >&2; exit 1; }

# ---------------------------------------------------------------- fetching

if command -v curl >/dev/null 2>&1; then
	fetch() { curl -fsSL "$1" -o "$2"; }
	fetch_stdout() { curl -fsSL "$1"; }
elif command -v wget >/dev/null 2>&1; then
	fetch() { wget -q "$1" -O "$2"; }
	fetch_stdout() { wget -q "$1" -O -; }
else
	die "neither curl nor wget is available"
fi

# ---------------------------------------------------------------- platform

os=$(uname -s 2>/dev/null || echo unknown)
arch=$(uname -m 2>/dev/null || echo unknown)

case "$os" in
Darwin) os=macos ;;
Linux) os=linux ;;
MINGW* | MSYS* | CYGWIN* | Windows_NT)
	die "this installer is for macOS and Linux. On Windows, download
             $DOWNLOADS/mde-<version>-windows-<arch>.zip, unpack it, and run
             mde.exe --install" ;;
*) die "unsupported operating system: $os" ;;
esac

case "$arch" in
arm64 | aarch64) arch=arm64 ;;
x86_64 | amd64) arch=amd64 ;;
*) die "unsupported architecture: $arch" ;;
esac

# ---------------------------------------------------------------- checksums

tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT INT TERM

say "Looking up the current release"
fetch "$DOWNLOADS/SHA256SUMS" "$tmp/SHA256SUMS" ||
	die "cannot reach $DOWNLOADS/SHA256SUMS"

# The checksum file names every archive, so it settles both the version and the
# hash in one round trip: no separate version file to drift out of step.
if [ -n "${MDE_VERSION:-}" ]; then
	name="mde-$MDE_VERSION-$os-$arch.tar.gz"
	grep -q " \./\{0,1\}$name\$" "$tmp/SHA256SUMS" ||
		die "version $MDE_VERSION has no build for $os-$arch"
else
	name=$(sed -n "s|^[0-9a-f]\{64\}  \./\{0,1\}\(mde-.*-$os-$arch\.tar\.gz\)\$|\1|p" \
		"$tmp/SHA256SUMS" | sort -V | tail -1)
	[ -n "$name" ] || die "no build listed for $os-$arch"
fi

version=$(echo "$name" | sed -e 's/^mde-//' -e "s/-$os-$arch\.tar\.gz\$//")
want=$(sed -n "s|^\([0-9a-f]\{64\}\)  \./\{0,1\}$name\$|\1|p" "$tmp/SHA256SUMS" | head -1)

# ---------------------------------------------------------------- download

say "Downloading mde $version for $os/$arch"
fetch "$DOWNLOADS/$name" "$tmp/$name" || die "cannot download $DOWNLOADS/$name"

if [ "${MDE_SKIP_VERIFY:-0}" = "1" ]; then
	say "Skipping the checksum, because MDE_SKIP_VERIFY is set"
else
	if command -v shasum >/dev/null 2>&1; then
		got=$(shasum -a 256 "$tmp/$name" | cut -d' ' -f1)
	elif command -v sha256sum >/dev/null 2>&1; then
		got=$(sha256sum "$tmp/$name" | cut -d' ' -f1)
	else
		die "no shasum or sha256sum to check the download with;
             set MDE_SKIP_VERIFY=1 to install without checking"
	fi
	[ -n "$want" ] || die "no checksum published for $name"
	[ "$got" = "$want" ] ||
		die "the download does not match its published checksum.
             Expected $want
             Got      $got
             Nothing was installed."
	say "Checksum matches"
fi

# ---------------------------------------------------------------- install

tar -xzf "$tmp/$name" -C "$tmp" || die "cannot unpack $name"
root="$tmp/${name%.tar.gz}"
[ -x "$root/mde" ] || die "the archive does not contain the binary it should"

# mde installs itself: the same code path as the Install item in its Help menu,
# so there is one implementation of "put this on the PATH" and not two.
if [ -n "${MDE_INSTALL_DIR:-}" ]; then
	"$root/mde" --install-dir "$MDE_INSTALL_DIR"
else
	"$root/mde" --install
fi

# The samples are what make the graph and the wikilinks demonstrable straight
# away, so they are kept rather than thrown out with the temporary directory.
share=${XDG_DATA_HOME:-$HOME/.local/share}/mde
if [ -d "$root/samples" ]; then
	mkdir -p "$share"
	rm -rf "$share/samples"
	cp -R "$root/samples" "$share/samples"
	echo
	say "Sample documents are in $share/samples"
	say "Try them with: mde $share/samples/sample.md"
fi
