#!/bin/sh
# Install Etiquette from a signed release tarball into a user-local prefix.
set -eu

BASE_URL=${ETIQUETTE_INSTALL_BASE_URL:-https://etiquekit.com/releases}
VERSION=${ETIQUETTE_INSTALL_VERSION:-latest}
INSTALL_ROOT=${ETIQUETTE_INSTALL_ROOT:-"$HOME/.etiquette"}
PUBLIC_KEY=${ETIQUETTE_RELEASE_PUBLIC_KEY:-}
PUBLIC_KEY_URL=${ETIQUETTE_RELEASE_PUBLIC_KEY_URL:-}
PUBLIC_KEY_SHA256=${ETIQUETTE_RELEASE_PUBLIC_KEY_SHA256:-}
MODIFY_PROFILE=0

usage() {
  cat <<'USAGE'
usage: install.sh [--version <version>] [--base-url <url>] [--install-root <path>] [--public-key <path>] [--public-key-url <url>] [--public-key-sha256 <hex>] [--modify-profile]

Environment:
  ETIQUETTE_INSTALL_BASE_URL      release base URL, default https://etiquekit.com/releases
  ETIQUETTE_INSTALL_VERSION       release version or latest
  ETIQUETTE_INSTALL_ROOT          install root, default ~/.etiquette
  ETIQUETTE_RELEASE_PUBLIC_KEY    RSA public key used to verify SHA256SUMS.sig
  ETIQUETTE_RELEASE_PUBLIC_KEY_URL
                                  HTTPS or file URL for the RSA public key
  ETIQUETTE_RELEASE_PUBLIC_KEY_SHA256
                                  expected SHA-256 hex for a downloaded public key
USAGE
}

while [ "$#" -gt 0 ]; do
  case "$1" in
    --version) VERSION=${2:?missing version}; shift 2 ;;
    --base-url) BASE_URL=${2:?missing base URL}; shift 2 ;;
    --install-root) INSTALL_ROOT=${2:?missing install root}; shift 2 ;;
    --public-key) PUBLIC_KEY=${2:?missing public key}; shift 2 ;;
    --public-key-url) PUBLIC_KEY_URL=${2:?missing public key URL}; shift 2 ;;
    --public-key-sha256) PUBLIC_KEY_SHA256=${2:?missing public key SHA-256}; shift 2 ;;
    --modify-profile) MODIFY_PROFILE=1; shift ;;
    -h|--help) usage; exit 0 ;;
    *) echo "install.sh: unknown argument: $1" >&2; usage >&2; exit 64 ;;
  esac
done

need() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "install.sh: missing required command: $1" >&2
    exit 127
  fi
}

need curl
need bun
need openssl
need shasum
need tar

TMPDIR_ROOT=${TMPDIR:-/tmp}
TMP=$(mktemp -d "$TMPDIR_ROOT/etiquette-install.XXXXXX")
trap 'rm -rf "$TMP"' EXIT INT TERM

if [ -n "$PUBLIC_KEY" ] && [ -n "$PUBLIC_KEY_URL" ]; then
  echo "install.sh: use either --public-key or --public-key-url, not both" >&2
  exit 64
fi

if [ -n "$PUBLIC_KEY" ]; then
  if [ ! -f "$PUBLIC_KEY" ]; then
    echo "install.sh: public key path does not exist: $PUBLIC_KEY" >&2
    exit 1
  fi
elif [ -n "$PUBLIC_KEY_URL" ]; then
  if [ -z "$PUBLIC_KEY_SHA256" ]; then
    echo "install.sh: --public-key-url requires --public-key-sha256" >&2
    exit 1
  fi
  PUBLIC_KEY="$TMP/etiquette-release.pub"
  curl -fsSL "$PUBLIC_KEY_URL" -o "$PUBLIC_KEY"
  ACTUAL_KEY_SHA=$(shasum -a 256 "$PUBLIC_KEY" | awk '{ print $1 }')
  if [ "$PUBLIC_KEY_SHA256" != "$ACTUAL_KEY_SHA" ]; then
    echo "install.sh: public key SHA-256 mismatch" >&2
    exit 1
  fi
else
  echo "install.sh: provide --public-key, or --public-key-url with --public-key-sha256" >&2
  exit 1
fi

RELEASE_URL="${BASE_URL%/}/$VERSION"
cd "$TMP"
curl -fsSLO "$RELEASE_URL/SHA256SUMS"
curl -fsSLO "$RELEASE_URL/SHA256SUMS.sig"
TARBALL=$(awk '/etiquette-[0-9][^ ]*\.tgz$/ { print $2; exit }' SHA256SUMS)
if [ -z "$TARBALL" ]; then
  echo "install.sh: SHA256SUMS does not name an etiquette release tarball" >&2
  exit 1
fi
curl -fsSLO "$RELEASE_URL/$TARBALL"

EXPECTED=$(awk -v file="$TARBALL" '$2 == file { print $1; exit }' SHA256SUMS)
ACTUAL=$(shasum -a 256 "$TARBALL" | awk '{ print $1 }')
if [ "$EXPECTED" != "$ACTUAL" ]; then
  echo "install.sh: checksum mismatch for $TARBALL" >&2
  exit 1
fi

openssl dgst -sha256 -verify "$PUBLIC_KEY" -signature SHA256SUMS.sig SHA256SUMS >/dev/null

VERSION_DIR=$(basename "$TARBALL" .tgz)
LIB_DIR="$INSTALL_ROOT/lib/$VERSION_DIR"
BIN_DIR="$INSTALL_ROOT/bin"
mkdir -p "$LIB_DIR" "$BIN_DIR"
tar -xzf "$TARBALL"
rm -rf "$LIB_DIR"
mkdir -p "$LIB_DIR"
cp -R package/. "$LIB_DIR/"
if [ -f "$LIB_DIR/package.json" ]; then
  (
    cd "$LIB_DIR"
    bun install --production >/dev/null
  )
fi
ln -sfn "$LIB_DIR/bin/etiquette" "$BIN_DIR/etiquette"
ln -sfn "$LIB_DIR/bin/etiquette-core" "$BIN_DIR/etiquette-core"

if [ "$MODIFY_PROFILE" -eq 1 ]; then
  PROFILE=${SHELL##*/}
  case "$PROFILE" in
    zsh) PROFILE_FILE="$HOME/.zshrc" ;;
    bash) PROFILE_FILE="$HOME/.bashrc" ;;
    *) PROFILE_FILE="$HOME/.profile" ;;
  esac
  LINE="export PATH=\"$BIN_DIR:\$PATH\""
  touch "$PROFILE_FILE"
  if ! grep -Fqx "$LINE" "$PROFILE_FILE"; then
    printf '\n# Etiquette CLI\n%s\n' "$LINE" >> "$PROFILE_FILE"
  fi
  echo "install.sh: updated $PROFILE_FILE"
else
  echo "install.sh: add $BIN_DIR to PATH, or rerun with --modify-profile"
fi

echo "install.sh: installed etiquette into $INSTALL_ROOT"
echo "install.sh: docs: https://etiquekit.com"
echo "install.sh: run: $BIN_DIR/etiquette doctor --project <workspace>"
echo "install.sh: agent skill integrations are explicit; no Claude/Codex/Gemini config was modified"
