#!/usr/bin/env bash
# AuraOffice, 0.4.4 for Linux x86_64, 0.2 for macOS Apple Silicon; List, 1.1.6 for Linux x86_64, 1.1.6 for macOS, Apple Silicon and Intel; Track, 0.4.4 for Linux x86_64, 0.1.4 for macOS Apple Silicon
#
#   curl -sSL https://auraoffice.org/install.sh | bash
#   curl -sSL https://auraoffice.org/install.sh | bash -s -- page list
#
# What this does, so that nobody has to run it to find out: it works out
# whether it is on Linux or a Mac, downloads that platform's tarball, checks it
# against the checksum below, extracts it to a temporary directory, and runs
# the installer inside it. It installs into your home directory and asks for no
# privileges. It prints what it did.
#
# List and Track have release lines of their own. The names decide what
# is downloaded: `list` fetches List's tarball, `track` fetches Track's,
# and any other name fetches the suite's. Names from several lines fetch and
# check every tarball before any installer runs.
# With no names it installs the suite, and List only when named.
#
# On a Mac this is the only way to install AuraOffice. The applications are not
# signed with an Apple developer identity, and the installer inside removes the
# quarantine flag Gatekeeper would otherwise refuse them for.
#
# The checksum is not protection against this server: it came from this server.
# It is protection against a download that arrived damaged or truncated, which
# is the failure that actually happens and is otherwise silent.
#
# Reading it before running it is the right instinct and this file is written
# to be read: no minification, no second stage, nothing fetched but the
# tarballs. It sticks to what the bash on a Mac (3.2) understands.
set -euo pipefail

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

SUITE_FILE=""; LIST_FILE=""; TRACK_FILE=""; SUITE_ARM64_ONLY=0
case "$(uname -s)" in
  Linux)
    SYSTEM="Linux"; GLOB="*/linux/install.sh"
    SUITE_FILE="auraoffice-0.4.4-r12-linux-x86_64.tar.gz"; SUITE_SHA="ff9cad8bad337493f9bc325e72172cd7ac922904b4751cfb94ae112919ca7a95"; SUITE_URL="https://auraoffice.org/releases/auraoffice-0.4.4-r12-linux-x86_64.tar.gz"
    SUITE_LABEL="AuraOffice 0.4.4 for Linux x86_64, 55.2 MB"
    LIST_FILE="auralist-1.1.6-linux-x86_64.tar.gz"; LIST_SHA="5bea63f6025e703bfa63ecff0b406d31f21f25b94d6a1d49f291ccca0da01e27"; LIST_URL="https://auraoffice.org/releases/auralist-1.1.6-linux-x86_64.tar.gz"
    LIST_LABEL="List 1.1.6 for Linux x86_64, 11.2 MB"
    TRACK_FILE="auratrack-0.4.4-linux-x86_64.tar.gz"; TRACK_SHA="502a0abf5ee29f858043f5cfc902d0f7b2ffcd7ceb4c61f370fc8797634d4e65"; TRACK_URL="https://auraoffice.org/releases/auratrack-0.4.4-linux-x86_64.tar.gz"
    TRACK_LABEL="Track 0.4.4 for Linux x86_64, 5.1 MB"
    ;;
  Darwin)
    SYSTEM="macOS"; GLOB="*/macos/install.sh"
    SUITE_FILE="auraoffice-0.2-r4-macos-arm64.tar.gz"; SUITE_SHA="cd912322ab2a7711c9ccccb756383a3df27fd457b18b6819a38c4523cb56e421"; SUITE_URL="https://auraoffice.org/releases/auraoffice-0.2-r4-macos-arm64.tar.gz"
    SUITE_LABEL="AuraOffice 0.2 for macOS Apple Silicon, 43.7 MB"
    SUITE_ARM64_ONLY=1
    LIST_FILE="auralist-1.1.6-macos-universal.tar.gz"; LIST_SHA="b079bc9c017470f3cd5107091e0e182ec999810e3e3b287d767cd5729653110f"; LIST_URL="https://auraoffice.org/releases/auralist-1.1.6-macos-universal.tar.gz"
    LIST_LABEL="List 1.1.6 for macOS, Apple Silicon and Intel, 20.8 MB"
    TRACK_FILE="auratrack-0.1.4-macos-arm64.tar.gz"; TRACK_SHA="2fedc556e327127beffb26c3d788435445cc3d373acbe71712666fa641bb8c15"; TRACK_URL="https://auraoffice.org/releases/auratrack-0.1.4-macos-arm64.tar.gz"
    TRACK_LABEL="Track 0.1.4 for macOS Apple Silicon, 4.3 MB"
    ;;
  *) die "AuraOffice installs on Linux and macOS with this script; on Windows, use https://auraoffice.org/install.ps1 or the installer from https://auraoffice.org/download/" ;;
esac
LIST_IN_PLAIN_RUN=0

# Which installer each argument goes to. Options go to both, and each keeps
# its place among the names: `--uninstall page` has to reach the installer as
# `--uninstall page`, since `--uninstall` followed by an option removes
# everything. `list` and `track` go to their product tarballs and every other
# name goes to the suite's; the installers refuse a name they do not know.
suite_args=(); list_args=(); track_args=(); want_suite=0; want_list=0; want_track=0; named=0
while [ $# -gt 0 ]; do
  case "$1" in
    --prefix)
      [ $# -ge 2 ] || die "--prefix needs a directory"
      suite_args+=("$1" "$2"); list_args+=("$1" "$2"); track_args+=("$1" "$2"); shift ;;
    -*) suite_args+=("$1"); list_args+=("$1"); track_args+=("$1") ;;
    list|auralist) list_args+=(list); want_list=1; named=1 ;;
    track|auratrack) track_args+=(track); want_track=1; named=1 ;;
    *) suite_args+=("$1"); want_suite=1; named=1 ;;
  esac
  shift
done
if [ "$named" = 0 ]; then
  want_suite=1
  if [ "$LIST_IN_PLAIN_RUN" = 1 ] && [ -n "$LIST_FILE" ]; then want_list=1; list_args+=(list); fi
fi

if [ "$want_suite" = 1 ] && [ -z "$SUITE_FILE" ]; then
  if [ "$named" = 0 ] && [ -n "$LIST_FILE" ]; then
    die "there is no AuraOffice build for $SYSTEM published yet. List has one: put list after bash -s -- to install it."
  fi
  die "there is no AuraOffice build for $SYSTEM published yet. See https://auraoffice.org/download/"
fi
if [ "$want_list" = 1 ] && [ -z "$LIST_FILE" ]; then
  die "there is no List build for $SYSTEM published yet. See https://auraoffice.org/download/"
fi
if [ "$want_track" = 1 ] && [ -z "$TRACK_FILE" ]; then
  die "there is no Track build for $SYSTEM published yet. See https://auraoffice.org/download/"
fi
if [ "$want_suite" = 1 ] && [ "$SUITE_ARM64_ONLY" = 1 ] && [ "$(uname -m)" != arm64 ]; then
  die "this build is for Apple Silicon Macs, and this Mac is $(uname -m)"
fi

command -v curl >/dev/null || die "curl is needed and is not here"
command -v tar  >/dev/null || die "tar is needed and is not here"
if command -v sha256sum >/dev/null; then sum() { sha256sum "$1" | cut -d' ' -f1; }
elif command -v shasum >/dev/null; then sum() { shasum -a 256 "$1" | cut -d' ' -f1; }
else die "sha256sum or shasum is needed and neither is here"; fi

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

# Download one tarball and check it. Every tarball is checked before any
# installer runs, so a bad download leaves nothing half installed.
fetch() { # fetch <label> <url> <file> <sha256>
  say "$1"
  say "  from $2"
  curl -fSL --progress-bar -o "$tmp/$3" "$2" || die "the download failed"
  SHA="$4"
  got="$(sum "$tmp/$3")"
  if [ "$got" != "$SHA" ]; then
    die "$3 does not match its checksum, so it is not being installed.
     expected $SHA
     got      $got
     Try again; if it happens twice, say so instead of working around it."
  fi
  say "  checksum matches"
}

# Extract one tarball into a directory of its own and find its installer.
unpack() { # unpack <file> <directory under tmp>; sets inner
  dir="$tmp/$2"
  mkdir -p "$dir"
  tar -xzf "$tmp/$1" -C "$dir" || die "$1 would not extract"
  # The tarball unpacks to <name>/<platform>/install.sh, three deep from here
  # and not two. The first version of this line looked two deep, downloaded
  # 27 MB, checked the sum, extracted it and then said there was no installer
  # inside a tarball that had one. Found by running it against the live site.
  inner="$(find "${dir:-$tmp}" -maxdepth 3 -path "${GLOB:-*/linux/install.sh}" -type f | head -1)"
  [ -n "$inner" ] || die "there is no ${GLOB#\*/} inside $1"
}

if [ "$want_suite" = 1 ]; then fetch "$SUITE_LABEL" "$SUITE_URL" "$SUITE_FILE" "$SUITE_SHA"; fi
if [ "$want_list" = 1 ]; then fetch "$LIST_LABEL" "$LIST_URL" "$LIST_FILE" "$LIST_SHA"; fi
if [ "$want_track" = 1 ]; then fetch "$TRACK_LABEL" "$TRACK_URL" "$TRACK_FILE" "$TRACK_SHA"; fi

suite_inner=""; list_inner=""; track_inner=""
if [ "$want_suite" = 1 ]; then unpack "$SUITE_FILE" suite; suite_inner="$inner"; fi
if [ "$want_list" = 1 ]; then unpack "$LIST_FILE" list; list_inner="$inner"; fi
if [ "$want_track" = 1 ]; then unpack "$TRACK_FILE" track; track_inner="$inner"; fi

if [ -n "$suite_inner" ]; then
  say ""
  bash "$suite_inner" ${suite_args[@]+"${suite_args[@]}"}
fi
if [ -n "$list_inner" ]; then
  say ""
  bash "$list_inner" "${list_args[@]}"
fi
if [ -n "$track_inner" ]; then
  say ""
  bash "$track_inner" "${track_args[@]}"
fi
