#!/bin/sh
# Cyborb CLI installer · https://cyborb.ai/install
# Env: VERSION=x.y.z pins a version (used by `cyborb upgrade`); default latest.
set -e

printf '\n  * CYBORB\n  Autonomous software engineering, realized.\n\n'

DOWNLOAD_BASE="https://updates.cyborb.ai/cli"
INSTALL_DIR="$HOME/.cyborb/bin"

# --- platform detection ---------------------------------------------------
OS="$(uname -s 2>/dev/null || echo unknown)"
ARCH="$(uname -m 2>/dev/null || echo unknown)"
printf '  Detected: %s / %s\n' "$OS" "$ARCH"

case "$ARCH" in
  x86_64|amd64) ARCH_TAG="x64" ;;
  arm64|aarch64) ARCH_TAG="arm64" ;;
  *) printf '  Unsupported architecture: %s\n' "$ARCH"; exit 1 ;;
esac

# A shell running under Rosetta on an Apple Silicon Mac reports x86_64, and
# there is no Intel Mac build. sysctl reports the real chip, so use it.
if [ "$OS" = "Darwin" ] && [ "$ARCH_TAG" = "x64" ] \
   && [ "$(sysctl -n hw.optional.arm64 2>/dev/null)" = "1" ]; then
  ARCH_TAG="arm64"
  printf '  Apple Silicon under Rosetta: installing the native build.\n'
fi

case "$OS" in
  Darwin) ARTIFACT="cyborb-darwin-$ARCH_TAG" ;;
  Linux)  ARTIFACT="cyborb-linux-$ARCH_TAG" ;;
  *)
    printf '  This installer supports macOS and Linux.\n'
    printf '  On Windows, download the desktop app from https://cyborb.ai/download\n'
    exit 1
    ;;
esac

# --- download --------------------------------------------------------------
if [ -n "$VERSION" ]; then
  URL="https://updates.cyborb.ai/cli/v$VERSION/$ARTIFACT"
else
  URL="https://updates.cyborb.ai/cli/$ARTIFACT"
fi
printf '  Fetching %s\n' "$URL"

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
if ! curl -fSL --progress-bar "$URL" -o "$TMP/cyborb"; then
  # Ask for the status alone (the exit code is not reliable for this: over
  # HTTP/2 a 404 can surface as error 56). 404 means there is no such build.
  HTTP_STATUS="$(curl -sIL -o /dev/null -w '%{http_code}' "$URL" 2>/dev/null || true)"
  if [ "$HTTP_STATUS" != "404" ]; then
    printf '\n  The download did not finish. Check your connection and try again.\n'
  elif [ -n "$VERSION" ]; then
    printf '\n  Version %s has no build for %s / %s.\n' "$VERSION" "$OS" "$ARCH"
  elif [ "$ARTIFACT" = "cyborb-darwin-x64" ]; then
    printf '\n  Cyborb needs a Mac with Apple Silicon (M1 or later). Intel Macs are not supported.\n'
  else
    printf '\n  There is no Cyborb build for %s / %s yet.\n' "$OS" "$ARCH"
  fi
  printf '  See https://cyborb.ai/download for what is available today.\n\n'
  exit 1
fi

mkdir -p "$INSTALL_DIR"
mv -f "$TMP/cyborb" "$INSTALL_DIR/cyborb"
chmod 755 "$INSTALL_DIR/cyborb"

# --- verify -----------------------------------------------------------------
"$INSTALL_DIR/cyborb" --version >/dev/null 2>&1 || {
  printf '  Installed, but the binary failed to run on this system.\n'
  printf '  Please report this at https://cyborb.ai and include your OS and CPU.\n'
  exit 1
}
printf '\n  Installed: %s\n' "$INSTALL_DIR/cyborb"

# --- skills -----------------------------------------------------------------
# The agent finds skills by scanning the filesystem, and a bare binary sees
# only the one built-in. Without this the CLI has no /publish, /motion,
# /web-design, /site-analytics or /build-from-url, while the desktop app (which
# stages the same skills beside its own copy) has all of them. Verified on the
# shipped binary: 1 skill before, 6 after.
#
# $XDG_CONFIG_HOME/cyborb (default ~/.config/cyborb) is scanned for
# {skill,skills}/**/SKILL.md, so extracting the tarball's top-level skills/
# there needs no config file. The archive holds only our own skill directories,
# so a skill the user wrote themselves is left alone. Failure here is not fatal:
# the CLI still runs, it just has fewer skills.
SKILLS_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/cyborb"
if curl -fSL --silent --max-filesize 52428800 "https://updates.cyborb.ai/cli/skills.tar.gz" -o "$TMP/skills.tar.gz"; then
  # Unpack only our own skills/ tree. A member with an absolute path or a ".."
  # segment would write outside SKILLS_DIR, so the archive is listed and
  # checked BEFORE anything is written, and then unpacked into a scratch
  # directory so a rejected or truncated archive leaves nothing behind. The
  # list check is the real guard; tar hardening flags are deliberately not used
  # because --no-same-owner is absent from busybox tar and would fail the
  # install on minimal Linux images, while ownership is not restored for a
  # non-root user anyway.
  if tar -tzf "$TMP/skills.tar.gz" > "$TMP/skills.list" 2>/dev/null \
     && [ -s "$TMP/skills.list" ] \
     && ! grep -qvE '^skills/' "$TMP/skills.list" \
     && ! grep -qE '(^|/)\.\.(/|$)' "$TMP/skills.list" \
     && mkdir -p "$TMP/unpack" "$SKILLS_DIR/skills" \
     && tar -xzf "$TMP/skills.tar.gz" -C "$TMP/unpack" 2>/dev/null \
     && cp -R "$TMP/unpack/skills/." "$SKILLS_DIR/skills/"; then
    printf '  Skills:    %s\n' "$SKILLS_DIR/skills"
  else
    printf '  Skills could not be unpacked; the CLI will run without them.\n'
  fi
else
  printf '  Skills could not be downloaded; the CLI will run without them.\n'
fi

# --- PATH -------------------------------------------------------------------
# Shell startup files are never edited. If the install folder is not on PATH,
# say which line to add and where, and give the next steps with the full path
# so they work in this terminal right away. Output only: exit status is the
# same either way (cyborb upgrade runs this script too).
case ":$PATH:" in
  *":$INSTALL_DIR:"*|*":$INSTALL_DIR/:"*)
    printf '\n  Next:\n    cyborb login    # opens your browser\n    cyborb          # start the agent\n\n'
    ;;
  *)
    PATH_LINE='export PATH="$HOME/.cyborb/bin:$PATH"'
    case "${SHELL##*/}" in
      zsh)  RC_FILE="~/.zshrc" ;;
      bash) if [ "$OS" = "Darwin" ]; then RC_FILE="~/.bash_profile"; else RC_FILE="~/.bashrc"; fi ;;
      fish) RC_FILE="~/.config/fish/config.fish"; PATH_LINE='fish_add_path $HOME/.cyborb/bin' ;;
      *)    RC_FILE="~/.profile" ;;
    esac
    printf '\n  ~/.cyborb/bin is not on your PATH, so typing just "cyborb" will not work yet.\n'
    printf '  To fix that for new terminals, add this line to %s:\n\n    %s\n' "$RC_FILE" "$PATH_LINE"
    printf '\n  Next (works right now):\n'
    printf '    ~/.cyborb/bin/cyborb login    # opens your browser\n'
    printf '    ~/.cyborb/bin/cyborb          # start the agent\n\n'
    ;;
esac
