#!/bin/sh
set -e
# Nadir bootstrap installer.
#
# Detects the host architecture, fetches the latest release asset from the
# Gitea releases API, and installs it as a systemd service:
#
#   curl -fsSL https://<existing-nadir-host>:<port>/install.sh | sudo sh
#
# The binary always comes from the Gitea release (not the source instance),
# so the installed copy is guaranteed to be the latest tagged build,
# independent of whatever version the serving host happens to be running.
#
# Everything is wrapped in do_install and invoked on the last line, the same
# pattern get.docker.com uses: when piped via `curl | sh`, sh executes while
# still receiving bytes from the network. Defining the whole body as a
# function before running anything means sh has fully parsed the script
# before do_install ever runs.

# Where to look for releases. Substituted at request time by the server
# (cmd/server/server.go) so the script knows which Gitea instance owns
# this deployment. Example: https://gitea.example.com/urania/nadir
RELEASE_REPO="__NADIR_RELEASE_REPO__"

do_install() {
  if [ "$(id -u)" -ne 0 ]; then
    echo "this script must be run as root (try piping through 'sudo sh')" >&2
    exit 1
  fi

  if ! command -v curl >/dev/null 2>&1; then
    echo "curl is required" >&2
    exit 1
  fi

  case "$(uname -m)" in
    x86_64|amd64)        arch=amd64 ;;
    aarch64|arm64)       arch=arm64 ;;
    *) echo "unsupported architecture: $(uname -m) (only amd64 and arm64 are built)" >&2; exit 1 ;;
  esac

  api="$RELEASE_REPO/releases/latest"
  api="${api%/}"
  # Convert https://host/owner/repo/releases/latest into Gitea API form.
  # Splits the URL once on '/' between host and path, inserts /api/v1/repos.
  host=$(echo "$RELEASE_REPO" | awk -F/ '{print $1"//"$3}')
  path=$(echo "$RELEASE_REPO" | awk -F/ '{print $4"/"$5}')
  api="$host/api/v1/repos/$path/releases/latest"

  echo "querying $api ..."
  asset_url=$(curl -fsSL "$api" \
    | grep -o '"browser_download_url":"[^"]*linux-'"$arch"'"' \
    | head -n1 \
    | cut -d'"' -f4)

  if [ -z "$asset_url" ]; then
    echo "no linux-$arch asset found in the latest release at $api" >&2
    exit 1
  fi

  echo "downloading $asset_url ..."
  curl -f --progress-bar -L "$asset_url" -o /usr/local/bin/nadir.tmp

  asset_name=$(basename "$asset_url")

  # Verify SHA-256: download the checksums file published alongside the binary
  # and confirm the hash matches. This catches CDN corruption and (together with
  # the HTTPS transport) makes tampered binaries detectable.
  sums_url="$host/api/v1/repos/$path/releases/latest"
  sums_asset_url=$(curl -fsSL "$sums_url" \
    | grep -o '"browser_download_url":"[^"]*sha256sums\.txt"' \
    | head -n1 \
    | cut -d'"' -f4)

  if [ -n "$sums_asset_url" ]; then
    echo "verifying checksum ..."
    curl -fsSL "$sums_asset_url" -o /tmp/nadir-sha256sums.txt
    # Extract the expected hash for our asset and compare.
    expected=$(grep "$asset_name" /tmp/nadir-sha256sums.txt | awk '{print $1}')
    actual=$(sha256sum /usr/local/bin/nadir.tmp | awk '{print $1}')
    rm -f /tmp/nadir-sha256sums.txt
    if [ -z "$expected" ]; then
      echo "warning: sha256sums.txt does not contain a hash for $asset_name" >&2
      echo "proceeding without verification" >&2
    elif [ "$expected" != "$actual" ]; then
      echo "SHA-256 MISMATCH: expected $expected, got $actual" >&2
      echo "the downloaded binary may be corrupted or tampered with — aborting" >&2
      rm -f /usr/local/bin/nadir.tmp
      exit 1
    else
      echo "checksum OK ($actual)"
    fi
  else
    echo "warning: no sha256sums.txt in release — skipping verification" >&2
  fi

  mv /usr/local/bin/nadir.tmp /usr/local/bin/nadir
  chmod +x /usr/local/bin/nadir

  echo "binary installed at /usr/local/bin/nadir"
  echo "installing as a systemd service ..."
  if [ -c /dev/tty ]; then
    /usr/local/bin/nadir install < /dev/tty
  else
    /usr/local/bin/nadir install
  fi

  echo
  echo "done. check status with: nadir status"
}

do_install
