#!/bin/sh
# memcode installer — https://memcode.ai
#
#   curl -fsSL https://memcode.ai/install.sh | sh
#
# Detects your OS/arch, downloads the matching release from GitHub, verifies the
# checksum, and installs the `memcode` binary. Override with env vars:
#
#   MEMCODE_VERSION=v0.3.1   install a specific tag (default: latest)
#   MEMCODE_INSTALL_DIR=...  install location (default: /usr/local/bin or ~/.local/bin)
#
set -eu

REPO="memcode-ai/memcode"
BINARY="memcode"

# --- pretty output -----------------------------------------------------------
if [ -t 1 ]; then
  BOLD="$(printf '\033[1m')"; DIM="$(printf '\033[2m')"
  RED="$(printf '\033[31m')"; GREEN="$(printf '\033[32m')"; RESET="$(printf '\033[0m')"
else
  BOLD=""; DIM=""; RED=""; GREEN=""; RESET=""
fi
info() { printf '%s\n' "${DIM}›${RESET} $*"; }
ok()   { printf '%s\n' "${GREEN}✓${RESET} $*"; }
err()  { printf '%s\n' "${RED}✗ $*${RESET}" >&2; }
die()  { err "$@"; exit 1; }

# --- prerequisites -----------------------------------------------------------
if command -v curl >/dev/null 2>&1; then
  DL="curl -fsSL"
elif command -v wget >/dev/null 2>&1; then
  DL="wget -qO-"
else
  die "need curl or wget to download memcode"
fi
command -v tar >/dev/null 2>&1 || die "need tar to extract the archive"

# --- detect platform ---------------------------------------------------------
os="$(uname -s)"
arch="$(uname -m)"

case "$os" in
  Linux)  OS="Linux" ;;
  Darwin) OS="Darwin" ;;
  MINGW*|MSYS*|CYGWIN*) die "for Windows, run in PowerShell: irm https://memcode.ai/install.ps1 | iex (or use WSL)" ;;
  *) die "unsupported OS: $os" ;;
esac

case "$arch" in
  x86_64|amd64) ARCH="x86_64" ;;
  arm64|aarch64) ARCH="arm64" ;;
  *) die "unsupported architecture: $arch" ;;
esac

# --- resolve version ---------------------------------------------------------
# Downloads funnel through memcode.ai/dl (a rewrite to GitHub Releases), so the
# underlying host can change without touching this script.
VERSION="${MEMCODE_VERSION:-latest}"
if [ "$VERSION" = "latest" ]; then
  BASE="https://memcode.ai/dl"
else
  BASE="https://github.com/$REPO/releases/download/$VERSION"
fi

ARCHIVE="${BINARY}_${OS}_${ARCH}.tar.gz"
URL="$BASE/$ARCHIVE"

info "Installing ${BOLD}${BINARY}${RESET} (${OS}/${ARCH}, ${VERSION})"

# --- download & verify -------------------------------------------------------
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT INT TERM

info "Downloading $ARCHIVE"
$DL "$URL" > "$TMP/$ARCHIVE" || die "download failed: $URL"
[ -s "$TMP/$ARCHIVE" ] || die "downloaded archive is empty — does release $VERSION exist?"

# Best-effort checksum verification (skipped if checksums.txt is unavailable).
if $DL "$BASE/checksums.txt" > "$TMP/checksums.txt" 2>/dev/null && [ -s "$TMP/checksums.txt" ]; then
  if command -v sha256sum >/dev/null 2>&1; then SHA="sha256sum"; elif command -v shasum >/dev/null 2>&1; then SHA="shasum -a 256"; else SHA=""; fi
  if [ -n "$SHA" ]; then
    expected="$(grep " $ARCHIVE\$" "$TMP/checksums.txt" | awk '{print $1}')"
    actual="$(cd "$TMP" && $SHA "$ARCHIVE" | awk '{print $1}')"
    if [ -n "$expected" ] && [ "$expected" != "$actual" ]; then
      die "checksum mismatch for $ARCHIVE"
    fi
    [ -n "$expected" ] && ok "Checksum verified"
  fi
fi

info "Extracting"
tar -xzf "$TMP/$ARCHIVE" -C "$TMP" || die "failed to extract archive"
[ -f "$TMP/$BINARY" ] || die "binary not found in archive"
chmod +x "$TMP/$BINARY"

# --- choose install dir ------------------------------------------------------
if [ -n "${MEMCODE_INSTALL_DIR:-}" ]; then
  DIR="$MEMCODE_INSTALL_DIR"
elif [ -w "/usr/local/bin" ] 2>/dev/null; then
  DIR="/usr/local/bin"
else
  DIR="$HOME/.local/bin"
fi
mkdir -p "$DIR"

DEST="$DIR/$BINARY"
if mv "$TMP/$BINARY" "$DEST" 2>/dev/null; then
  :
elif command -v sudo >/dev/null 2>&1 && [ -t 0 ]; then
  info "Elevating with sudo to write $DIR"
  sudo mv "$TMP/$BINARY" "$DEST"
else
  die "cannot write to $DIR — set MEMCODE_INSTALL_DIR to a writable path"
fi

ok "Installed ${BOLD}${BINARY}${RESET} to $DEST"

# --- PATH hint ---------------------------------------------------------------
case ":$PATH:" in
  *":$DIR:"*) ;;
  *) printf '%s\n' "${DIM}  $DIR is not on your PATH — add it:${RESET}"
     printf '%s\n' "    export PATH="$DIR:$PATH"" ;;
esac

printf '\n'

# --- jump straight into first-run setup --------------------------------------
# When installed via curl | sh, this script's stdin is the pipe, not the
# terminal. If a real terminal is attached, offer to launch memcode now with
# /dev/tty reattached so its first-run wizard can read your input.
if [ ! -t 0 ] && { : > /dev/tty; } 2>/dev/null; then
  printf '%s' "${BOLD}Start $BINARY now?${RESET} [Y/n] " > /dev/tty
  read ans < /dev/tty || ans=""
  case "$ans" in
    n|N|no|No|NO) ok "Run ${BOLD}$BINARY${RESET} when you're ready, or ${BOLD}$BINARY --help${RESET}." ;;
    *) exec "$DEST" < /dev/tty > /dev/tty 2>&1 ;;
  esac
else
  ok "Run ${BOLD}$BINARY${RESET} to get started, or ${BOLD}$BINARY --help${RESET}."
fi
