#!/bin/sh
# sitereal installer — curl -fsSL https://get.sitereal.app | sh
#
# Downloads one self-contained binary and the builder UI beside it. No Node, no
# npm, no compiler, and nothing is asked of you: this script never prompts,
# because when it runs through a pipe its stdin is the script itself.
#
# It also never uses sudo. Everything lands under $HOME, which is the whole
# reason this can be a paste rather than a password.
#
# Unsigned, and that is the point: macOS quarantines what a *browser*
# downloads, not what curl does, so these bytes run where the same file fetched
# from a download page would not.
set -eu

BASE="${SITEREAL_BASE:-https://get.sitereal.app}"
HOME_DIR="${SITEREAL_HOME:-$HOME/.sitereal}"

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

command -v curl >/dev/null 2>&1 || die "curl is needed and was not found."
command -v tar  >/dev/null 2>&1 || die "tar is needed and was not found."

# ---- which build ------------------------------------------------------------
os=$(uname -s)
arch=$(uname -m)
case "$os" in
  Darwin) os=darwin ;;
  Linux)  os=linux ;;
  *) die "unsupported system: $os. On Windows use the PowerShell installer:
  irm $BASE/install.ps1 | iex" ;;
esac
case "$arch" in
  arm64|aarch64) arch=arm64 ;;
  x86_64|amd64)  arch=x64 ;;
  *) die "unsupported processor: $arch" ;;
esac
target="$os-$arch"

say ""
say "  sitereal — installing for $target"

# ---- what to download -------------------------------------------------------
# The manifest names the archive and what it must hash to. A checksum is the
# only integrity check an unsigned download has, so it is not skippable here.
manifest=$(curl -fsSL "$BASE/latest.json") || die "could not reach $BASE"

field() { printf '%s' "$manifest" | tr -d '\n ' | sed -n "s/.*\"$target\":{[^}]*\"$1\":\"\([^\"]*\)\".*/\1/p"; }
file=$(field file)
want=$(field sha256)
[ -n "$file" ] || die "this release has no build for $target."
[ -n "$want" ] || die "the release manifest is missing a checksum for $target."

tmp=$(mktemp -d "${TMPDIR:-/tmp}/sitereal.XXXXXX") || die "could not make a temporary folder"
# Cleaned up whichever way this ends, including Ctrl-C.
trap 'rm -rf "$tmp"' EXIT INT TERM

# https is required of the real thing and not of SITEREAL_BASE, which exists so
# a release can be served from somewhere else — a mirror, a company's own host,
# a machine testing this script.
case "$BASE" in
  https://*) proto="--proto =https --tlsv1.2" ;;
  *) proto="" ;;
esac

say "  downloading $file"
# shellcheck disable=SC2086
curl -fsSL $proto -o "$tmp/$file" "$BASE/$file" || die "download failed"

if command -v shasum >/dev/null 2>&1; then got=$(shasum -a 256 "$tmp/$file" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then got=$(sha256sum "$tmp/$file" | cut -d' ' -f1)
else die "neither shasum nor sha256sum is available, so the download cannot be verified."
fi
[ "$got" = "$want" ] || die "checksum mismatch — the download is not what the release says it should be.
  expected $want
  got      $got"
say "  checksum ok"

# ---- install ----------------------------------------------------------------
mkdir -p "$tmp/unpacked"
tar -xzf "$tmp/$file" -C "$tmp/unpacked" || die "the archive could not be unpacked"
[ -x "$tmp/unpacked/bin/sitereal" ] || die "the archive does not contain what it should"

# Old install moved aside rather than deleted, and only removed once the new
# one is in place: an interrupted install must not be able to leave you with
# neither.
if [ -d "$HOME_DIR" ]; then rm -rf "$HOME_DIR.old"; mv "$HOME_DIR" "$HOME_DIR.old"; fi
mkdir -p "$(dirname "$HOME_DIR")"
mv "$tmp/unpacked" "$HOME_DIR"
rm -rf "$HOME_DIR.old"

BIN="$HOME_DIR/bin"

# ---- put it on PATH ---------------------------------------------------------
# Preferred: a folder already on PATH that we can write to, so no shell config
# is touched at all. Only if there is none do we edit an rc file, and then only
# by appending a line that is not already there.
on_path=0
case ":$PATH:" in *":$BIN:"*) on_path=1 ;; esac

linked=""
if [ "$on_path" -eq 0 ]; then
  for dir in "$HOME/.local/bin" "/usr/local/bin"; do
    case ":$PATH:" in *":$dir:"*) ;; *) continue ;; esac
    [ -w "$dir" ] || continue
    ln -sf "$BIN/sitereal" "$dir/sitereal" && linked="$dir" && on_path=1
    break
  done
fi

added=""
if [ "$on_path" -eq 0 ]; then
  line="export PATH=\"$BIN:\$PATH\""
  for rc in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile"; do
    [ -f "$rc" ] || continue
    grep -qF "$BIN" "$rc" 2>/dev/null && continue
    printf '\n# sitereal\n%s\n' "$line" >> "$rc"
    added="${added:+$added }$rc"
  done
fi

version=$("$BIN/sitereal" --version 2>/dev/null || echo "?")

say ""
say "  ✓ sitereal $version → $HOME_DIR"
[ -n "$linked" ] && say "    linked into $linked"
[ -n "$added" ] && say "    added to PATH in:$added"
say ""
if [ "$on_path" -eq 1 ] && [ -z "$added" ]; then
  say "  Open a project:"
  say ""
  say "      cd my-site && sitereal"
else
  say "  Open a new terminal, then:"
  say ""
  say "      cd my-site && sitereal"
  say ""
  say "  Or use it right away without one:"
  say ""
  say "      $BIN/sitereal"
fi
say ""
say "  It starts in the folder you are standing in and opens the builder"
say "  in your browser. Docs: https://docs.sitereal.app"
say ""
