#!/bin/sh
# Rauta CLI installer -- https://rauta.ai/docs
#
#   curl -fsSL https://rauta.ai/cli/install.sh | sh
#
# Downloads the static binary for this platform and installs it as `rauta-ai`
# (also linked as `rauta` when possible). Prefers CDN artifacts named rauta-*;
# falls back to infra-arena-* during the interim rename window.
#
# Environment:
#   RAUTA_CLI_BASE      download from a mirror instead of the public CDN
#   RAUTA_INSTALL_DIR   install here instead of /usr/local/bin or ~/.local/bin
#
# Everything is verified BEFORE the binary is moved onto $PATH. A CDN that has
# lost a path answers 200 with the website's index.html rather than 404, and the
# previous version of this script moved that HTML to $dest/rauta-ai and only
# then tried to run it -- leaving a broken `rauta-ai` on the user's PATH and
# reporting a shell error about it. Now the download is staged inside the
# destination directory (so the final step is an atomic rename on the same
# filesystem), checked for an executable header, checked against a published
# sha256 when one exists, and actually run once, all while the cleanup trap is
# still armed. If any check fails, nothing is installed.
set -eu

PRIMARY_BASE="${RAUTA_CLI_BASE:-${INFRA_ARENA_CLI_BASE:-https://rauta.ai/cli}}"
FALLBACK_BASE="https://rauta.ai/cli"
DOCS="https://rauta.ai/docs"

if ! command -v curl >/dev/null 2>&1; then
  echo "error: curl is required to download the Rauta CLI and was not found." >&2
  echo "Nothing was installed." >&2
  echo "Next step: install curl, or use the Node path instead -- npx rauta-ai init" >&2
  exit 1
fi

os=$(uname -s | tr '[:upper:]' '[:lower:]')
arch=$(uname -m)
case "$os" in
  darwin|linux) ;;
  *)
    echo "error: unsupported OS '$os' (darwin and linux builds are published)" >&2
    echo "Nothing was installed. See $DOCS for other ways to run Rauta." >&2
    exit 1 ;;
esac
case "$arch" in
  arm64|aarch64) arch=arm64 ;;
  x86_64|amd64)  arch=amd64 ;;
  *)
    echo "error: unsupported architecture '$arch' (arm64 and amd64 builds are published)" >&2
    echo "Nothing was installed. See $DOCS for other ways to run Rauta." >&2
    exit 1 ;;
esac

# Pick the destination first so the download can be staged there: `mv` within a
# directory is an atomic rename, and the "does it actually run" check below then
# runs on the very filesystem that will host the binary.
dest="${RAUTA_INSTALL_DIR:-}"
if [ -z "$dest" ]; then
  dest=/usr/local/bin
  if [ ! -w "$dest" ]; then
    dest="$HOME/.local/bin"
  fi
fi
mkdir -p "$dest" 2>/dev/null || true
if [ ! -w "$dest" ]; then
  echo "error: cannot write to $dest, so the CLI cannot be installed there." >&2
  echo "Nothing was installed." >&2
  echo "Next step: choose a directory you own -- RAUTA_INSTALL_DIR=\$HOME/bin sh install.sh" >&2
  exit 1
fi

tmp=$(mktemp "$dest/.rauta-ai.download.XXXXXX")
trap 'rm -f "$tmp"' EXIT INT TERM

download_ok=0
source_url=""
attempts=""
saw_http=0
saw_html=0
seen=""
# Prefer brand name, then legacy; try primary host then fallback host.
# Deduplicate when env override makes PRIMARY === FALLBACK.
# When an operator points this at a mirror, use ONLY that mirror. Silently
# reaching out to the public CDN behind their back can breach an egress policy
# and makes the failure confusing when it happens. The second base exists for
# the artifact RENAME window, not for host failover -- by default both constants
# are the same host, so there is no failover to lose.
if [ -n "${RAUTA_CLI_BASE:-}" ] || [ -n "${INFRA_ARENA_CLI_BASE:-}" ]; then
  bases="$PRIMARY_BASE"
else
  bases="$PRIMARY_BASE $FALLBACK_BASE"
fi
for artifact in "rauta-$os-$arch" "infra-arena-$os-$arch"; do
  for base in $bases; do
    url="$base/$artifact"
    case " $seen " in
      *" $url "*) continue ;;
    esac
    seen="$seen $url"
    echo "Downloading $url"
    # -sS keeps the progress meter quiet but still lets curl print its own
    # diagnosis; --write-out adds the status code even when -f makes curl exit
    # non-zero, so a failure can name the URL AND what the server said. "000"
    # means no HTTP response arrived at all, the signature of no route out.
    code=000
    rc=0
    code=$(curl -fsSL --write-out '%{http_code}' -o "$tmp" "$url") || rc=$?
    if [ -z "$code" ]; then
      code=000
    fi
    if [ "$rc" -ne 0 ]; then
      if [ "$code" != "000" ]; then
        saw_http=1
      fi
      attempts="$attempts
  $url
    HTTP $code (curl exit $rc)"
      continue
    fi
    saw_http=1
    # A 200 is not proof of an artifact. Measured against production on
    # 2026-08-11: every missing path under /cli/ answers 200 with the website,
    # so curl NEVER fails and this loop would always stop on the first URL --
    # making the fallback list dead code. Checking the bytes here is what makes
    # trying the next candidate possible at all.
    #
    # ELF is linux; the feed/cafe families are Mach-O, thin and universal.
    magic=$(od -An -v -tx1 -N4 "$tmp" 2>/dev/null | tr -d ' \n' || true)
    case "$magic" in
      7f454c46|feedface|feedfacf|cefaedfe|cffaedfe|cafebabe|bebafeca)
        download_ok=1
        source_url="$url"
        break 2 ;;
    esac
    saw_html=1
    attempts="$attempts
  $url
    HTTP $code, but did not send an executable (first bytes '$magic')"
  done
done

if [ "$download_ok" -ne 1 ]; then
  echo "error: could not download the Rauta CLI for $os/$arch." >&2
  echo "Tried, in order:$attempts" >&2
  echo "Nothing was installed -- $dest is untouched." >&2
  if [ "$saw_http" -eq 0 ]; then
    echo "Every attempt failed before the CDN answered, which usually means no route out." >&2
    echo "If you are behind an egress proxy or use an internal mirror, point the installer at it." >&2
    # The variable goes on the `sh`, not on the `curl`: this script is what
    # reads it, and it is the right-hand side of the pipe.
    echo "  curl -fsSL $FALLBACK_BASE/install.sh | RAUTA_CLI_BASE=https://mirror.example.com/cli sh" >&2
  elif [ "$saw_html" -eq 1 ]; then
    echo "A 200 carrying a web page means the CDN has no artifact at that path: the" >&2
    echo "release is still deploying, or this version was never published." >&2
    echo "Next step: retry in a few minutes, or check $DOCS for the current version." >&2
  else
    echo "Next step: check $DOCS for the current install command, or set RAUTA_CLI_BASE" >&2
    echo "to a mirror that carries the artifact above." >&2
  fi
  exit 1
fi

# 2. Integrity, when the release publishes it. No `.sha256` file is emitted
#    today (see scripts/build-cli.sh), so a missing one is a warning rather than
#    a failure -- hard-failing here would break every install the day this ships.
#    The sidecar is fetched the same way as the binary, so it can come back as
#    the same HTML fallback. Anything that is not exactly 64 hex characters is
#    treated as "not published" rather than as a mismatch.
published=""
if published=$(curl -fsSL "$source_url.sha256" 2>/dev/null); then
  published=$(printf '%s' "$published" | awk 'NR==1 {print $1}')
else
  published=""
fi
if [ ${#published} -ne 64 ]; then
  published=""
else
  case "$published" in
    *[!0-9a-fA-F]*) published="" ;;
  esac
fi
if [ -n "$published" ]; then
  actual=""
  if command -v sha256sum >/dev/null 2>&1; then
    actual=$(sha256sum "$tmp" | awk '{print $1}')
  elif command -v shasum >/dev/null 2>&1; then
    actual=$(shasum -a 256 "$tmp" | awk '{print $1}')
  fi
  if [ -z "$actual" ]; then
    echo "note: no sha256sum or shasum on this machine, so integrity was not verified."
  elif [ "$actual" != "$published" ]; then
    echo "error: the binary from $source_url does not match its published checksum." >&2
    echo "       expected $published" >&2
    echo "       actual   $actual" >&2
    echo "       The download was corrupted or tampered with in transit." >&2
    echo "Nothing was installed -- $dest is untouched." >&2
    echo "Next step: retry on a different network, or report it at $DOCS" >&2
    exit 1
  fi
else
  echo "note: no checksum published at $source_url.sha256, so integrity was not verified."
fi

# 3. Does it actually run here? Still staged, so a failure installs nothing.
#    An explicit 755, not `chmod +x`: mktemp creates the staging file 0600, so
#    `+x` left it 0711 -- executable by everyone but readable only by the owner,
#    which is the wrong mode for a shared /usr/local/bin.
chmod 755 "$tmp"
if ! version=$("$tmp" version 2>&1); then
  echo "error: the binary downloaded from $source_url will not run on this machine." >&2
  echo "       It said: $version" >&2
  echo "Nothing was installed -- $dest is untouched." >&2
  echo "Next step: report the output above with your OS and CPU at $DOCS" >&2
  exit 1
fi

mv "$tmp" "$dest/rauta-ai"
trap - EXIT INT TERM
ln -sf "$dest/rauta-ai" "$dest/rauta" 2>/dev/null || true

echo "Installed $version to $dest/rauta-ai"
case ":$PATH:" in
  *":$dest:"*) ;;
  *) echo "note: $dest is not on your PATH -- add it to your shell profile" ;;
esac
echo "Get started: rauta-ai init   (or: npx rauta-ai init)"
