#!/bin/sh
# Synchronex Agent Bridge installer (macOS / Linux).
#
# Usage:   curl -fsSL https://synchronex.ai/bridge/install.sh | sh
# Inspect: open https://synchronex.ai/bridge/install.sh first — you should read
#          any script before piping it to a shell.
#
# What it does, and how it is kept safe:
#   * Downloads a prebuilt binary + checksums.txt from Synchronex's public R2
#     bucket over HTTPS/TLS only (the same zero-egress bucket that serves
#     rendered video). NOT GitHub releases: kmdesle/synchronex is a private
#     repo, so unauthenticated release-asset downloads 404 regardless of
#     whether the asset exists -- R2 is the real, working distribution path.
#   * Verifies the binary's SHA-256 against checksums.txt and REFUSES to install
#     on any mismatch. Only after verification, runs the installed binary to
#     pair your account and register auto-start. Set SYNCHRONEX_NO_START=1 to
#     install without running it.
#   * Installs to a user directory (~/.local/bin) — never uses sudo.
#   * Persists that directory in one shell profile and updates PATH for this
#     installer session.
# It does NOT read, store, or transmit your provider CLI credentials.

set -eu

INSTALL_NAME="synchronex-agent-bridge"
BIN_DIR="${SYNCHRONEX_BIN_DIR:-$HOME/.local/bin}"
R2_PUBLIC_BASE="https://pub-2ec492d5da7240edb06cb0114ce1be7b.r2.dev/bridge"
DAEMON_INSTALL_UNCONFIRMED_EXIT_CODE=2

# Default to the latest release; pin a specific version with
# SYNCHRONEX_BRIDGE_VERSION=0.5.0 (resolves bridge/agent-bridge-v0.5.0/... in R2).
if [ -n "${SYNCHRONEX_BRIDGE_VERSION:-}" ]; then
  BASE="${R2_PUBLIC_BASE}/agent-bridge-v${SYNCHRONEX_BRIDGE_VERSION}"
else
  BASE="${R2_PUBLIC_BASE}/latest"
fi

die() { echo "install: $1" >&2; exit 1; }

# ── Resolve the right binary for this OS/arch ────────────────────────────────
os="$(uname -s)"
arch="$(uname -m)"
case "$os" in
  Darwin)
    case "$arch" in
      arm64) asset="agent-bridge-mac-arm64" ;;
      x86_64) asset="agent-bridge-mac-x64" ;;
      *) die "unsupported macOS arch '$arch' — run 'npx @synchronex/agent-bridge' instead" ;;
    esac ;;
  Linux)
    case "$arch" in
      x86_64|amd64) asset="agent-bridge-linux-x64" ;;
      *) die "unsupported Linux arch '$arch' — run 'npx @synchronex/agent-bridge' instead" ;;
    esac ;;
  *) die "unsupported OS '$os' — run 'npx @synchronex/agent-bridge' instead" ;;
esac

command -v curl >/dev/null 2>&1 || die "curl is required"

# ── Download to a temp dir (cleaned up on any exit) ──────────────────────────
tmp="$(mktemp -d)"
mkdir -p "$BIN_DIR"
staged="${BIN_DIR}/.${INSTALL_NAME}.new"
trap 'rm -rf "$tmp"; rm -f "$staged"' EXIT INT TERM

fetch() {
  # HTTPS + TLS 1.2+ enforced; fail on HTTP errors; follow redirects only within https.
  curl -fsSL --proto '=https' --tlsv1.2 "$1" -o "$2" || die "download failed: $1"
}

echo "Downloading the Synchronex bridge..."
fetch "${BASE}/${asset}" "$staged"
fetch "${BASE}/checksums.txt" "${tmp}/checksums.txt"
echo "Download complete."

# ── Verify SHA-256 before trusting the binary ────────────────────────────────
expected="$(awk -v f="$asset" '$2 == f || $2 == "*"f {print $1}' "${tmp}/checksums.txt" | head -n1)"
[ -n "$expected" ] || die "no checksum published for ${asset} — refusing to install"

if command -v sha256sum >/dev/null 2>&1; then
  actual="$(sha256sum "$staged" | awk '{print $1}')"
elif command -v shasum >/dev/null 2>&1; then
  actual="$(shasum -a 256 "$staged" | awk '{print $1}')"
else
  die "no SHA-256 tool (sha256sum/shasum) found — cannot verify download"
fi

[ "$expected" = "$actual" ] || die "checksum mismatch for ${asset} — refusing to install (expected ${expected}, got ${actual})"

# ── Install (no sudo) ────────────────────────────────────────────────────────
dest="${BIN_DIR}/${INSTALL_NAME}"
# The staged file is next to its destination, so this move is always a rename
# on one filesystem and remains safe when the installed binary is running.
mv -f "$staged" "$dest"
chmod +x "$dest"

echo "✓ Installed ${INSTALL_NAME} to ${BIN_DIR}"

persist_path() {
  case ":$PATH:" in
    *":$BIN_DIR:"*) return ;;
  esac

  case "$(basename "${SHELL:-/bin/sh}")" in
    zsh) profile="$HOME/.zshrc" ;;
    bash) case "$os" in Darwin) profile="$HOME/.bash_profile" ;; *) profile="$HOME/.bashrc" ;; esac ;;
    *) profile="$HOME/.profile" ;;
  esac

  marker="# Added by the Synchronex Agent Bridge installer"
  if [ ! -f "$profile" ] || ! grep -qF "$marker" "$profile" 2>/dev/null; then
    { echo ""; echo "$marker"; echo "export PATH=\"${BIN_DIR}:\$PATH\""; } >> "$profile"
    echo "  Added ${BIN_DIR} to your PATH in ${profile} (open a new terminal to pick it up)."
  fi
  export PATH="${BIN_DIR}:$PATH"
}

registration_targets_installed_binary() {
  [ -f "$service_path" ] || return 1
  registration_content="$(cat "$service_path" 2>/dev/null)" || return 1
  case "$os" in
    Darwin)
      printf '%s\n' "$registration_content" | grep -qF "<string>${dest}</string>" || return 1
      printf '%s\n' "$registration_content" | grep -qF '<string>run</string>' || return 1
      ;;
    *)
      if printf '%s\n' "$registration_content" | grep -qF "ExecStart=${dest} run"; then
        :
      elif printf '%s\n' "$registration_content" | grep -qF "ExecStart=\"${dest}\" run"; then
        :
      else
        return 1
      fi
      ;;
  esac
  if printf '%s\n' "$registration_content" | grep -qi 'npx'; then
    return 1
  fi
  return 0
}

persist_path

if [ "${SYNCHRONEX_NO_START:-}" = "1" ]; then
  echo "Installed only (SYNCHRONEX_NO_START=1). Open a new terminal and run:  synchronex-agent-bridge"
  exit 0
fi

echo "Checking your AI tools and your Synchronex connection. This can take up to a minute..."
status_output="$("$dest" status 2>&1)" || true
case "$status_output" in
  *"No Synchronex account is paired on this device."*)
    echo ""
    echo "A browser window will open. Approve the connection there. If it opens in a browser where you're not signed in, copy the link shown below into the right one."
    if ! "$dest" connect; then
      echo ""
      echo "Pairing did not complete. Open a new terminal and run:  synchronex-agent-bridge connect"
      exit 0
    fi
    ;;
  *)
    echo "Already paired with Synchronex."
    ;;
esac

case "$os" in
  Darwin) service_path="$HOME/Library/LaunchAgents/ai.synchronex.agent-bridge.plist" ;;
  *) service_path="$HOME/.config/systemd/user/synchronex-agent-bridge.service" ;;
esac

daemon_reported_unconfirmed=""
daemon_already_registered=""
if registration_targets_installed_binary; then
  echo "Auto-start already registered."
  daemon_already_registered="1"
else
  echo "Registering auto-start so the bridge survives restarts..."
  if [ -f "$service_path" ]; then
    if SYNCHRONEX_AGENT_BRIDGE_BIN="$dest" "$dest" install --daemon --force; then
      daemon_exit=0
    else
      daemon_exit=$?
    fi
  else
    if SYNCHRONEX_AGENT_BRIDGE_BIN="$dest" "$dest" install --daemon; then
      daemon_exit=0
    else
      daemon_exit=$?
    fi
  fi

  if [ "$daemon_exit" -ne 0 ] && [ "$daemon_exit" -ne "$DAEMON_INSTALL_UNCONFIRMED_EXIT_CODE" ]; then
    echo ""
    echo "Auto-start registration failed. Open a new terminal and run:  synchronex-agent-bridge install --daemon"
    exit 0
  fi

  if ! registration_targets_installed_binary; then
    echo "Warning: Auto-start was registered, but its launcher does not point to the installed bridge binary."
    exit 0
  fi

  if [ "$daemon_exit" -eq "$DAEMON_INSTALL_UNCONFIRMED_EXIT_CODE" ]; then
    daemon_reported_unconfirmed="1"
  fi
fi

echo "If you ever need a command, open a new terminal and type:  synchronex-agent-bridge status"
echo ""
if [ "$daemon_already_registered" = "1" ]; then
  echo "Done. Auto-start is already registered, so the bridge starts automatically when you sign in. Run 'synchronex-agent-bridge status' to check whether it is running right now."
elif [ "$daemon_reported_unconfirmed" = "1" ]; then
  echo "Done. Auto-start is registered, but the bridge hasn't confirmed it's online yet. Run 'synchronex-agent-bridge status' to check, or look at the log if it stays offline."
else
  echo "Done. The bridge is running and will start automatically when you sign in. You can close this window."
fi
