#!/bin/sh
#
# Installs the fundaia binary for this platform.
#
# Written for `sh` rather than `bash`: this is piped into a shell on machines
# nobody chose, and Debian's `/bin/sh` is dash. Every construct below is POSIX.
#
# It never uses sudo and never edits a shell profile. Installing into a
# directory the user already owns, and *saying* when that directory is not on
# PATH, is more honest than a script that quietly appends to `.zshrc` — which is
# the line people regret having piped into a shell.

set -eu

REPO="alex28042/fundaia-apps"
BINARY="fundaia"
INSTALL_DIR="${FUNDAIA_INSTALL_DIR:-$HOME/.local/bin}"

say() { printf '  %s\n' "$1"; }
die() { printf '\n  error: %s\n\n' "$1" >&2; exit 1; }

need() {
  command -v "$1" >/dev/null 2>&1 || die "this needs $1, which is not installed"
}

need curl
need tar

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

target_triple() {
  os="$(uname -s)"
  arch="$(uname -m)"

  case "$os" in
    Darwin) os_part="apple-darwin" ;;
    Linux)  os_part="unknown-linux-gnu" ;;
    *) die "there is no prebuilt binary for $os — try: cargo install $BINARY" ;;
  esac

  case "$arch" in
    x86_64 | amd64) arch_part="x86_64" ;;
    arm64 | aarch64) arch_part="aarch64" ;;
    *) die "there is no prebuilt binary for $arch — try: cargo install $BINARY" ;;
  esac

  printf '%s-%s' "$arch_part" "$os_part"
}

TARGET="$(target_triple)"

# The tag is resolved rather than assumed, so the script keeps working after a
# release without being edited. `latest` redirects to the tagged URL, and the
# redirect target is what names the version.
VERSION="${FUNDAIA_VERSION:-}"
if [ -z "$VERSION" ]; then
  VERSION="$(curl -fsSLI -o /dev/null -w '%{url_effective}' \
    "https://github.com/$REPO/releases/latest" | sed 's#.*/tag/##')"
fi
[ -n "$VERSION" ] || die "could not work out the latest version"

ARCHIVE="$BINARY-$VERSION-$TARGET.tar.gz"
BASE="https://github.com/$REPO/releases/download/$VERSION"

printf '\n'
say "$BINARY $VERSION for $TARGET"

WORK="$(mktemp -d)"
# Cleaned up on the way out however it goes: an aborted download must not leave
# a half-extracted binary in a temporary directory nobody looks at.
trap 'rm -rf "$WORK"' EXIT INT TERM

say "descargando…"
curl -fsSL "$BASE/$ARCHIVE" -o "$WORK/$ARCHIVE" \
  || die "could not download $ARCHIVE — check the release has an asset for $TARGET"

# ---------------------------------------------------------------- checksum

if curl -fsSL "$BASE/$ARCHIVE.sha256" -o "$WORK/$ARCHIVE.sha256" 2>/dev/null; then
  expected="$(cut -d' ' -f1 < "$WORK/$ARCHIVE.sha256")"

  if command -v sha256sum >/dev/null 2>&1; then
    actual="$(sha256sum "$WORK/$ARCHIVE" | cut -d' ' -f1)"
  elif command -v shasum >/dev/null 2>&1; then
    actual="$(shasum -a 256 "$WORK/$ARCHIVE" | cut -d' ' -f1)"
  else
    actual=""
    say "sin sha256sum ni shasum: no se ha podido verificar la descarga"
  fi

  if [ -n "$actual" ] && [ "$actual" != "$expected" ]; then
    die "the checksum does not match — refusing to install"
  fi
  [ -n "$actual" ] && say "checksum correcto"
else
  say "la release no publica checksum: no se ha podido verificar la descarga"
fi

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

tar -xzf "$WORK/$ARCHIVE" -C "$WORK" || die "could not unpack $ARCHIVE"
[ -f "$WORK/$BINARY" ] || die "$ARCHIVE does not contain $BINARY"

mkdir -p "$INSTALL_DIR" || die "could not create $INSTALL_DIR"
# Moved into place rather than copied over a running binary: replacing the
# inode leaves an open process on the old one instead of corrupting it.
mv "$WORK/$BINARY" "$INSTALL_DIR/$BINARY.new" || die "could not write to $INSTALL_DIR"
chmod +x "$INSTALL_DIR/$BINARY.new"
mv "$INSTALL_DIR/$BINARY.new" "$INSTALL_DIR/$BINARY"

say "instalado en $INSTALL_DIR/$BINARY"

case ":$PATH:" in
  *":$INSTALL_DIR:"*) ;;
  *)
    printf '\n'
    say "$INSTALL_DIR no está en tu PATH. Añade esta línea a tu shell:"
    printf '\n      export PATH="%s:$PATH"\n' "$INSTALL_DIR"
    ;;
esac

printf '\n'
say "Empieza con:  $BINARY login --url https://infrastructure.fundaia.com"
printf '\n'
