#!/usr/bin/env sh
set -eu

APP_NAME="ai-indexer"
BIN_NAME="ai-indexer-mcp"
VERSION="${AI_INDEXER_VERSION:-latest}"
INSTALL_DIR="${AI_INDEXER_INSTALL_DIR:-$HOME/.local/bin}"
SUPPORT_DIR="${AI_INDEXER_SUPPORT_DIR:-$HOME/.ai-indexer}"
RELEASE_BASE="${AI_INDEXER_RELEASE_BASE:-https://aindex.floriansola.fr/releases}"

need() {
  command -v "$1" >/dev/null 2>&1 || {
    echo "$1 is required" >&2
    exit 1
  }
}

need uname
need tar
need grep

if command -v curl >/dev/null 2>&1; then
  fetch() { curl -fsSL "$1" -o "$2"; }
elif command -v wget >/dev/null 2>&1; then
  fetch() { wget -q "$1" -O "$2"; }
else
  echo "curl or wget is required" >&2
  exit 1
fi

os="$(uname -s | tr '[:upper:]' '[:lower:]')"
arch="$(uname -m)"
case "$arch" in
  arm64|aarch64) arch="aarch64" ;;
  x86_64|amd64) arch="x86_64" ;;
  *) echo "Unsupported architecture: $arch" >&2; exit 1 ;;
esac

case "$os" in
  darwin) target="${arch}-apple-darwin" ;;
  linux) target="${arch}-unknown-linux-gnu" ;;
  *) echo "Unsupported OS: $os" >&2; exit 1 ;;
esac
target="${AI_INDEXER_TARGET:-$target}"

tag="$VERSION"
if [ "$VERSION" = "latest" ]; then
  tag="latest"
elif echo "$VERSION" | grep -q '^v'; then
  tag="$VERSION"
else
  tag="v$VERSION"
fi

archive="${APP_NAME}-${tag}-${target}.tar.gz"
tmp="${TMPDIR:-/tmp}/${APP_NAME}-install-$$"
mkdir -p "$tmp" "$INSTALL_DIR"
cleanup() {
  rm -rf "$tmp"
}
trap cleanup EXIT

url="$RELEASE_BASE/$tag/$archive"
manifest_url="$RELEASE_BASE/$tag/release.json"
manifest="$tmp/release.json"

if fetch "$manifest_url" "$manifest"; then
  if ! grep -F "\"name\": \"$archive\"" "$manifest" >/dev/null 2>&1; then
    echo "No published AiIndexer archive for target: $target" >&2
    echo "Manifest: $manifest_url" >&2
    echo "Set AI_INDEXER_VERSION to a version that contains this target, or use one of the targets listed in the manifest." >&2
    exit 1
  fi
fi

echo "Downloading $url"
fetch "$url" "$tmp/$archive"

if [ "${AI_INDEXER_SKIP_CHECKSUM:-0}" != "1" ]; then
  fetch "$url.sha256" "$tmp/$archive.sha256"
  if command -v shasum >/dev/null 2>&1; then
    (cd "$tmp" && shasum -a 256 -c "$archive.sha256")
  elif command -v sha256sum >/dev/null 2>&1; then
    (cd "$tmp" && sha256sum -c "$archive.sha256")
  else
    echo "shasum or sha256sum is required for checksum verification" >&2
    exit 1
  fi
fi

if [ "${AI_INDEXER_SKIP_SIGNATURE:-0}" != "1" ]; then
  need python3
  need openssl
  fetch "$url.sig" "$tmp/$archive.sig"
  fetch "$RELEASE_BASE/$tag/release-public-key.txt" "$tmp/release-public-key.txt"
  python3 - "$tmp/release-public-key.txt" "$tmp/$archive.sig" "$tmp/release-public-key.der" "$tmp/$archive.sig.bin" <<'PY'
import base64
import pathlib
import sys

public_key_path, signature_path, der_path, signature_bin_path = map(pathlib.Path, sys.argv[1:])

def b64url_decode(value: str) -> bytes:
    value = ''.join(value.strip().split())
    return base64.urlsafe_b64decode(value + '=' * (-len(value) % 4))

public_key = b64url_decode(public_key_path.read_text())
signature = b64url_decode(signature_path.read_text())
if len(public_key) != 32:
    raise SystemExit('release public key must be 32 raw Ed25519 bytes')
if len(signature) != 64:
    raise SystemExit('release signature must be 64 raw Ed25519 bytes')

spki_ed25519_prefix = bytes.fromhex('302a300506032b6570032100')
der_path.write_bytes(spki_ed25519_prefix + public_key)
signature_bin_path.write_bytes(signature)
PY
  openssl pkey -pubin -inform DER -in "$tmp/release-public-key.der" -out "$tmp/release-public-key.pem" >/dev/null
  openssl pkeyutl -verify -pubin -inkey "$tmp/release-public-key.pem" -rawin -in "$tmp/$archive" -sigfile "$tmp/$archive.sig.bin" >/dev/null
  echo "Verified release signature for $archive"
else
  echo "Skipping release signature verification because AI_INDEXER_SKIP_SIGNATURE=1"
fi

tar -xzf "$tmp/$archive" -C "$tmp"
if [ ! -x "$tmp/$BIN_NAME" ]; then
  echo "$BIN_NAME missing from archive" >&2
  exit 1
fi

cp "$tmp/$BIN_NAME" "$INSTALL_DIR/$BIN_NAME"
chmod +x "$INSTALL_DIR/$BIN_NAME"
printf '%s\n' "$SUPPORT_DIR" > "$INSTALL_DIR/.ai-indexer-support-dir"
if [ -d "$tmp/scripts" ]; then
  mkdir -p "$SUPPORT_DIR/scripts"
  cp "$tmp/scripts"/*.sh "$SUPPORT_DIR/scripts/" 2>/dev/null || true
  chmod +x "$SUPPORT_DIR/scripts"/*.sh 2>/dev/null || true
fi

echo "Installed $BIN_NAME to $INSTALL_DIR/$BIN_NAME"
echo "Installed support scripts to $SUPPORT_DIR/scripts"
case ":${PATH:-}:" in
  *":$INSTALL_DIR:"*) bin_cmd="$BIN_NAME" ;;
  *) bin_cmd="$INSTALL_DIR/$BIN_NAME" ;;
esac

echo
echo "Next steps:"
if [ "$bin_cmd" = "$BIN_NAME" ]; then
  echo "  1. From your project: $BIN_NAME setup"
  echo "  2. Check setup:       $BIN_NAME doctor --repo ."
  echo "  3. Start MCP:        $BIN_NAME serve --repo ."
else
  echo "  1. Add AiIndexer to PATH for future shells:"
  echo "     export PATH=\"$INSTALL_DIR:\$PATH\""
  echo "  2. From your project now: \"$bin_cmd\" setup"
  echo "  3. Check setup now:        \"$bin_cmd\" doctor --repo ."
fi
echo "  Paid license: $bin_cmd license install <token>"
