#!/usr/bin/env bash
# DBSheriff bootstrap installer — served at https://get.dbsheriff.ai
#
#   curl -fsSL https://get.dbsheriff.ai | bash -s -- --version v1.2.0 --token '<download token>'
#
# Downloads the versioned install package from releases.dbsheriff.ai, checks
# it against SHA256SUMS (and the release's Sigstore signature when cosign is
# installed), unpacks it under /opt/dbsheriff/releases/<version>, points
# /opt/dbsheriff/current at it and hands over to the target's guided
# installer. Running it again with a newer --version is the upgrade path.
#
# Options
#   --version vX.Y.Z    release to install (required)
#   --token   '...'     download token from your DBSheriff release e-mail
#                       (or env DBSHERIFF_DOWNLOAD_TOKEN); it is the signed
#                       query string that unlocks releases/<version>/*
#   --target  onprem    deployment overlay: onprem (default) | aws
#   --dir     PATH      install root (default /opt/dbsheriff)
#   --package customer  package flavour: customer (default) | full
#   --base-url URL      where packages live (default https://releases.dbsheriff.ai)
#   --no-install        download, verify and unpack only
#   --skip-signature    do not verify the Sigstore signature even if cosign exists
set -euo pipefail

VERSION=""; TOKEN="${DBSHERIFF_DOWNLOAD_TOKEN:-}"; TARGET="onprem"; DIR="/opt/dbsheriff"
FLAVOUR="customer"; BASE_URL="${DBSHERIFF_RELEASES_URL:-https://releases.dbsheriff.ai}"
DO_INSTALL=1; VERIFY_SIG=1
while [ $# -gt 0 ]; do
  case "$1" in
    --version) VERSION="$2"; shift 2 ;;
    --token) TOKEN="$2"; shift 2 ;;
    --target) TARGET="$2"; shift 2 ;;
    --dir) DIR="$2"; shift 2 ;;
    --package) FLAVOUR="$2"; shift 2 ;;
    --base-url) BASE_URL="${2%/}"; shift 2 ;;
    --no-install) DO_INSTALL=0; shift ;;
    --skip-signature) VERIFY_SIG=0; shift ;;
    -h|--help) sed -n 2,24p "$0"; exit 0 ;;
    *) echo "unknown option: $1" >&2; exit 2 ;;
  esac
done

say()  { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
die()  { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; }

[ -n "$VERSION" ] || die "--version vX.Y.Z is required"
case "$VERSION" in v[0-9]*.[0-9]*.[0-9]*) ;; *) die "version must look like v1.2.0 (got $VERSION)";; esac
case "$TARGET" in onprem|aws) ;; *) die "--target must be onprem or aws";; esac
case "$FLAVOUR" in customer|full) ;; *) die "--package must be customer or full";; esac
for t in curl tar; do command -v "$t" >/dev/null || die "$t is required"; done
if command -v sha256sum >/dev/null; then SHA="sha256sum"; elif command -v shasum >/dev/null; then SHA="shasum -a 256"; else die "sha256sum or shasum is required"; fi
[ "$(id -u)" = 0 ] || [ -w "$(dirname "$DIR")" ] || [ -w "$DIR" ] 2>/dev/null || die "cannot write to $DIR — run as root or pass --dir"

BARE="${VERSION#v}"
PKG="dbsheriff-${BARE}-${VERSION}"; [ "$FLAVOUR" = customer ] && PKG="$PKG-customer"; PKG="$PKG.tar.gz"
Q=""; [ -n "$TOKEN" ] && Q="?${TOKEN#\?}"
url() { echo "$BASE_URL/$VERSION/$1$Q"; }

WORK=$(mktemp -d); trap 'rm -rf "$WORK"' EXIT
fetch() {  # fetch <name> [optional]   (curl's own error text is dropped: ours says what to do)
  if ! curl -fsL --retry 3 -o "$WORK/$1" "$(url "$1")" 2>/dev/null; then
    [ "${2:-}" = optional ] && return 1
    die "download failed: $BASE_URL/$VERSION/$1 (wrong version, or the download token is missing/expired)"
  fi
}

say "DBSheriff $VERSION ($FLAVOUR package, target $TARGET) -> $DIR"
say "downloading SHA256SUMS"
fetch SHA256SUMS
grep -q " $PKG\$" "$WORK/SHA256SUMS" || die "$PKG is not part of release $VERSION"

if [ "$VERIFY_SIG" = 1 ] && command -v cosign >/dev/null; then
  if fetch SHA256SUMS.sigstore.json optional; then
    say "verifying the release signature (Sigstore)"
    cosign verify-blob --bundle "$WORK/SHA256SUMS.sigstore.json" \
      --certificate-identity-regexp '^https://github.com/sduggira/dbsheriff/' \
      --certificate-oidc-issuer https://token.actions.githubusercontent.com \
      "$WORK/SHA256SUMS" >/dev/null 2>&1 || die "SHA256SUMS signature does not verify — do not install this download"
  else
    say "no signature published for $VERSION; checksum only"
  fi
elif [ "$VERIFY_SIG" = 1 ]; then
  say "cosign not installed; verifying checksums only (install cosign to verify the release signature)"
fi

say "downloading $PKG"
fetch "$PKG"
( cd "$WORK" && grep " $PKG\$" SHA256SUMS | $SHA -c - >/dev/null ) || die "checksum mismatch for $PKG"

REL="$DIR/releases/$VERSION"
say "unpacking to $REL"
mkdir -p "$REL" "$DIR/state"
tar -xzf "$WORK/$PKG" -C "$REL"
ln -sfn "$REL" "$DIR/current"
say "installed files: $DIR/current -> $REL"

[ "$DO_INSTALL" = 1 ] || { say "done (--no-install). Next: cd $DIR/current && deploy/$TARGET/install.sh"; exit 0; }
INSTALLER="$DIR/current/deploy/$TARGET/install.sh"
if [ -x "$INSTALLER" ] || [ -f "$INSTALLER" ]; then
  say "handing over to deploy/$TARGET/install.sh"
  cd "$DIR/current" && exec bash "deploy/$TARGET/install.sh"
else
  say "no guided installer for target '$TARGET' in this release yet; see $DIR/current/deploy/$TARGET/README.md"
fi
