#!/bin/sh
# Columbia Pages CLI installer.
#
#   curl -fsSL https://pages.col-agents.com/install | sh
#
# Downloads the current platform binary through the SvelteKit release
# endpoints, verifies it against the release checksum manifest, and installs
# it at ~/.local/bin/cpages by default.
set -eu

ORIGIN="${COLUMBIA_PAGES_ORIGIN:-https://pages.col-agents.com}"
INSTALL_DIR="${COLUMBIA_PAGES_INSTALL_DIR:-$HOME/.local/bin}"

log() {
  printf 'cpages-install: %s\n' "$*" >&2
}

die() {
  log "$*"
  exit 1
}

validate_origin() {
  case "$ORIGIN" in
    *@*) die "COLUMBIA_PAGES_ORIGIN must not contain URL credentials" ;;
    https://*) ;;
    http://localhost | http://localhost:* | http://127.0.0.1 | http://127.0.0.1:* | 'http://[::1]' | 'http://[::1]:'*) ;;
    *) die "COLUMBIA_PAGES_ORIGIN must use HTTPS (HTTP is allowed only for loopback development)" ;;
  esac
}

need() {
  command -v "$1" >/dev/null 2>&1 || die "'$1' is required to install cpages"
}

detect_os() {
  case "$(uname -s)" in
    Linux) echo linux ;;
    Darwin) echo darwin ;;
    *) die "unsupported OS: $(uname -s) (cpages ships Linux and macOS binaries)" ;;
  esac
}

detect_arch() {
  case "$(uname -m)" in
    x86_64 | amd64) echo amd64 ;;
    aarch64 | arm64) echo arm64 ;;
    *) die "unsupported architecture: $(uname -m) (cpages ships amd64 and arm64 binaries)" ;;
  esac
}

main() {
  need curl
  need uname
  need mktemp
  need mkdir
  need chmod
  need mv
  need cp
  need rm
  need awk

  validate_origin

  os=$(detect_os)
  arch=$(detect_arch)
  asset="cpages_${os}_${arch}"

  tmpdir=$(mktemp -d)
  install_tmp=''
  cleanup() {
    rm -rf "$tmpdir"
    [ -z "$install_tmp" ] || rm -f "$install_tmp"
  }
  trap cleanup EXIT INT TERM HUP

  log "resolving latest version..."
  version=$(curl -fsSL "${ORIGIN}/releases/latest") \
    || die "could not resolve the latest version from ${ORIGIN}/releases/latest"

  case "$version" in
    *[!0-9.]* | "" | .* | *. | *..* | *.*.*.*)
      die "unexpected version string from ${ORIGIN}/releases/latest: '${version}'" ;;
    *.*.*) ;;
    *) die "unexpected version string from ${ORIGIN}/releases/latest: '${version}'" ;;
  esac

  base_url="${ORIGIN}/releases/${version}"
  asset_url="${base_url}/${asset}"
  checksums_url="${base_url}/checksums.txt"

  log "downloading ${asset} ${version}..."
  curl -fsSL "$asset_url" -o "$tmpdir/$asset" \
    || die "download failed: $asset_url"
  curl -fsSL "$checksums_url" -o "$tmpdir/checksums.txt" \
    || die "download failed: $checksums_url"

  expected=$(awk -v want="$asset" '$2 == want { print $1; found=1 } END { if (!found) exit 1 }' "$tmpdir/checksums.txt") \
    || die "no checksum entry for ${asset} in checksums.txt"

  if command -v sha256sum >/dev/null 2>&1; then
    actual=$(sha256sum "$tmpdir/$asset" | awk '{ print $1 }')
  elif command -v shasum >/dev/null 2>&1; then
    actual=$(shasum -a 256 "$tmpdir/$asset" | awk '{ print $1 }')
  else
    die "neither sha256sum nor shasum found; cannot verify ${asset}"
  fi

  [ "$actual" = "$expected" ] \
    || die "checksum mismatch for ${asset}: got ${actual}, want ${expected}"

  mkdir -p "$INSTALL_DIR"
  install_tmp=$(mktemp "$INSTALL_DIR/.cpages.XXXXXX")
  cp "$tmpdir/$asset" "$install_tmp"
  chmod 0755 "$install_tmp"

  if installed=$("$install_tmp" version 2>/dev/null); then
    log "validated ${installed}"
  else
    die "downloaded binary did not run cleanly; existing installation was not changed"
  fi

  mv "$install_tmp" "$INSTALL_DIR/cpages"
  install_tmp=''

  log "installed cpages to ${INSTALL_DIR}/cpages"
  case ":${PATH}:" in
    *":${INSTALL_DIR}:"*) ;;
    *) log "note: add ${INSTALL_DIR} to your PATH" ;;
  esac

  log "${installed} ready"
  log "next: '${INSTALL_DIR}/cpages login --server <url>' to connect, '${INSTALL_DIR}/cpages skills install' for coding agents"
}

main "$@"
