#!/usr/bin/env bash
# CollabOps CLI installer.
#
# Detects the host platform, fetches the release manifest, picks the matching
# Go binary, verifies its sha256, and drops it at ~/.local/bin/co (override
# with CO_INSTALL_DIR). Pure Go binary — no Node/runtime dependencies.
#
# Usage:
#   curl -fsSL https://docs.collabops.ai/install.sh | bash
#
# Env overrides:
#   CO_INSTALL_URL_BASE  Manifest base URL (default: https://docs.collabops.ai/install/co)
#   CO_INSTALL_DIR       Where to drop the binary (default: ~/.local/bin)

set -euo pipefail

INSTALL_URL_BASE="${CO_INSTALL_URL_BASE:-https://docs.collabops.ai/install/co}"
INSTALL_URL_BASE="${INSTALL_URL_BASE%/}"
INSTALL_DIR="${CO_INSTALL_DIR:-$HOME/.local/bin}"
TARGET="$INSTALL_DIR/co"

echo ">> CollabOps CLI installer"
echo "   target: $TARGET"
echo "   source: $INSTALL_URL_BASE"
echo ""

# ── Required tooling ─────────────────────────────────────────────────────────
need() {
  command -v "$1" >/dev/null 2>&1 || {
    echo "error: '$1' is required but not found on PATH" >&2
    exit 1
  }
}
need curl

# JSON parsing relies on python3 (pre-installed on macOS 12.3+, every modern
# Linux distro, WSL). We avoid jq because it's not preinstalled on macOS.
need python3

# sha256: macOS ships `shasum`, Linux ships `sha256sum`. Either works.
if command -v sha256sum >/dev/null 2>&1; then
  SHA_CMD="sha256sum"
elif command -v shasum >/dev/null 2>&1; then
  SHA_CMD="shasum -a 256"
else
  echo "error: neither 'sha256sum' nor 'shasum' found — cannot verify download" >&2
  exit 1
fi

# ── Platform detection ───────────────────────────────────────────────────────
# uname -s   → GOOS
#   Darwin   → darwin
#   Linux    → linux
#   (others) → reject (Windows users build from source or use WSL)
#
# uname -m   → GOARCH
#   x86_64 / amd64           → amd64
#   arm64 / aarch64          → arm64
#   (others)                 → reject (report what we saw)
detect_platform() {
  local os arch
  os="$(uname -s)"
  arch="$(uname -m)"
  case "$os" in
    Darwin) os="darwin" ;;
    Linux)  os="linux"  ;;
    *)
      echo "error: unsupported OS '$os'. Supported: Darwin, Linux." >&2
      echo "       Windows users: install under WSL, or build from source." >&2
      exit 1
      ;;
  esac
  case "$arch" in
    x86_64|amd64)  arch="amd64" ;;
    arm64|aarch64) arch="arm64" ;;
    *)
      echo "error: unsupported CPU '$arch'. Supported: x86_64/amd64, arm64/aarch64." >&2
      exit 1
      ;;
  esac
  echo "$os/$arch"
}

PLATFORM="$(detect_platform)"
echo ">> detected platform: $PLATFORM"

# ── Fetch manifest ───────────────────────────────────────────────────────────
MANIFEST_URL="$INSTALL_URL_BASE/version.json"
MANIFEST_TMP="$(mktemp)"
trap 'rm -f "$MANIFEST_TMP"' EXIT

if ! curl -fSL "$MANIFEST_URL" -o "$MANIFEST_TMP" 2>/dev/null; then
  echo "error: failed to fetch manifest from $MANIFEST_URL" >&2
  echo "       check your network, or set CO_INSTALL_URL_BASE to a reachable mirror." >&2
  exit 1
fi

# ── Parse manifest → (url, sha256, version) for current platform ────────────
# Inline Python helper — heredoc provides the script via stdin (python3 -),
# the manifest path comes through argv[2]. `python3 -` plus a `<file` redirect
# would race for stdin, so we don't go that route.
PARSED="$(python3 - "$PLATFORM" "$MANIFEST_TMP" <<'PY'
import json, sys
platform, manifest_path = sys.argv[1], sys.argv[2]
with open(manifest_path) as f:
    m = json.load(f)
version = m.get("version") or sys.exit("manifest: missing 'version'")
bins = m.get("binaries") or sys.exit(
    "legacy manifest detected (no 'binaries' map). The TS-era release path "
    "is no longer supported by this installer — please retry after the "
    "next CLI release lands, or build from source."
)
entry = bins.get(platform)
if not entry:
    avail = ", ".join(sorted(bins.keys()))
    sys.exit(f"platform '{platform}' is not in the release matrix (available: {avail})")
url = entry.get("url"); sha = entry.get("sha256")
if not url or not sha:
    sys.exit(f"manifest entry for {platform} is missing url or sha256")
print(f"{version}\t{url}\t{sha}")
PY
)"

CLI_VERSION="$(printf '%s' "$PARSED" | cut -f1)"
REL_URL="$(printf '%s' "$PARSED" | cut -f2)"
WANT_SHA="$(printf '%s' "$PARSED" | cut -f3)"

echo "   version: $CLI_VERSION"
echo "   binary:  $INSTALL_URL_BASE/$REL_URL"
echo ""

# ── Download binary ──────────────────────────────────────────────────────────
echo ">> downloading..."
BIN_TMP="$(mktemp)"
trap 'rm -f "$MANIFEST_TMP" "$BIN_TMP"' EXIT
if ! curl -fSL "$INSTALL_URL_BASE/$REL_URL" -o "$BIN_TMP"; then
  echo "error: download failed from $INSTALL_URL_BASE/$REL_URL" >&2
  exit 1
fi

# ── Verify sha256 ────────────────────────────────────────────────────────────
GOT_SHA="$($SHA_CMD "$BIN_TMP" | awk '{print $1}')"
if [ "$GOT_SHA" != "$WANT_SHA" ]; then
  echo "error: sha256 mismatch — refusing to install" >&2
  echo "       want: $WANT_SHA" >&2
  echo "       got:  $GOT_SHA" >&2
  exit 1
fi
echo ">> sha256 verified: ${WANT_SHA:0:12}…"

# ── Install ──────────────────────────────────────────────────────────────────
mkdir -p "$INSTALL_DIR"
mv "$BIN_TMP" "$TARGET"
chmod +x "$TARGET"
trap 'rm -f "$MANIFEST_TMP"' EXIT

echo ">> verifying..."
if INSTALLED_VERSION="$("$TARGET" --version 2>/dev/null)"; then
  echo "   installed: $INSTALLED_VERSION"
else
  echo "error: '$TARGET --version' failed — the binary may be corrupted" >&2
  exit 1
fi

# ── PATH check ───────────────────────────────────────────────────────────────
case ":$PATH:" in
  *":$INSTALL_DIR:"*) PATH_OK=1 ;;
  *) PATH_OK=0 ;;
esac

echo ""
if [ "$PATH_OK" -eq 1 ]; then
  echo "✓ installed. run 'co auth login' to get started."
else
  echo "✓ installed at $TARGET"
  echo ""
  echo "⚠ $INSTALL_DIR is not on your PATH."
  echo "  add this line to your shell rc (~/.zshrc or ~/.bashrc):"
  echo ""
  echo "    export PATH=\"$INSTALL_DIR:\$PATH\""
  echo ""
  echo "  then reopen your terminal and run 'co auth login'."
fi
