#!/bin/sh
# Gecko installer — make any API agent-usable.
#   curl -fsSL https://get.geckovision.tech/install.sh | bash
#
# Downloads a prebuilt `gecko` binary (no uv/pip needed). Falls back to the
# uv path only for platforms we don't ship a binary for.
set -eu

REPO_BASE="https://github.com/GeckoVision/gecko-surf/releases/latest/download"
INSTALL_DIR="${HOME}/.local/bin"
BIN_PATH="${INSTALL_DIR}/gecko"
DOCS_URL="https://docs.geckovision.tech"

printf '\n  Installing gecko …\n\n'

# --- uv fallback: used for unsupported os/arch (incl. Windows/other) -----------
fallback_uv() {
  printf '  → no prebuilt binary for this platform; using the uv path.\n'
  if ! command -v uv >/dev/null 2>&1; then
    printf '  → installing uv (Python toolchain) …\n'
    curl -LsSf https://astral.sh/uv/install.sh | sh
    if [ -f "${HOME}/.local/bin/env" ]; then
      # shellcheck disable=SC1091
      . "${HOME}/.local/bin/env"
    else
      PATH="${HOME}/.local/bin:${PATH}"; export PATH
    fi
  fi
  uv tool install --upgrade "gecko-surf[serve]"
  printf '\n  gecko installed (via uv).\n'
  printf '    Try:   gecko <openapi-url>\n'
  printf '    Docs:  %s\n\n' "${DOCS_URL}"
  exit 0
}

# --- 1. detect platform -------------------------------------------------------
os="$(uname -s 2>/dev/null || echo unknown)"
arch="$(uname -m 2>/dev/null || echo unknown)"

case "${os}" in
  Linux)  os_tag="linux" ;;
  Darwin) os_tag="darwin" ;;
  *)      fallback_uv ;;
esac

case "${arch}" in
  x86_64 | amd64)   arch_tag="x86_64" ;;
  aarch64 | arm64)  arch_tag="arm64" ;;
  *)                fallback_uv ;;
esac

# --- 2. map to the exact published asset name + build the URL ------------------
asset="gecko-${os_tag}-${arch_tag}"
asset_url="${REPO_BASE}/${asset}"
sums_url="${REPO_BASE}/${asset}.sha256"

printf '  → platform: %s/%s  (asset: %s)\n' "${os_tag}" "${arch_tag}" "${asset}"

# --- 3. download binary + checksums, then verify ------------------------------
tmp_dir="$(mktemp -d 2>/dev/null || mktemp -d -t gecko)"
trap 'rm -rf "${tmp_dir}"' EXIT INT TERM
tmp_bin="${tmp_dir}/gecko"
tmp_sums="${tmp_dir}/${asset}.sha256"

printf '  → downloading %s …\n' "${asset}"
if ! curl -fsSL "${asset_url}" -o "${tmp_bin}"; then
  # No prebuilt binary for this platform (e.g. Intel macOS, or a transient 404).
  # Degrade gracefully to the uv path instead of hard-failing.
  printf '  ! no prebuilt binary for %s yet — using uv instead.\n' "${asset}" >&2
  fallback_uv
fi

printf '  → downloading checksum (%s.sha256) …\n' "${asset}"
if ! curl -fsSL "${sums_url}" -o "${tmp_sums}"; then
  printf '  ! checksum unavailable for %s — using uv instead.\n' "${asset}" >&2
  fallback_uv
fi

# Pull the expected checksum for our asset out of the SHA256SUMS file.
expected="$(awk -v a="${asset}" '$2 == a || $2 == "*"a {print $1; exit}' "${tmp_sums}")"
if [ -z "${expected}" ]; then
  printf '  ✗ no checksum entry for %s\n' "${asset}" >&2
  exit 1
fi

if command -v sha256sum >/dev/null 2>&1; then
  actual="$(sha256sum "${tmp_bin}" | awk '{print $1}')"
elif command -v shasum >/dev/null 2>&1; then
  actual="$(shasum -a 256 "${tmp_bin}" | awk '{print $1}')"
else
  actual=""
  printf '  ! no sha256sum/shasum found; skipping checksum verification.\n' >&2
fi

if [ -n "${actual}" ]; then
  if [ "${actual}" != "${expected}" ]; then
    printf '  ✗ checksum mismatch for %s\n' "${asset}" >&2
    printf '      expected: %s\n' "${expected}" >&2
    printf '      actual:   %s\n' "${actual}" >&2
    exit 1
  fi
  printf '  → checksum verified.\n'
fi

# --- 4. install ---------------------------------------------------------------
chmod +x "${tmp_bin}"
mkdir -p "${INSTALL_DIR}"
mv "${tmp_bin}" "${BIN_PATH}"

printf '\n  gecko installed to %s\n' "${BIN_PATH}"

case ":${PATH}:" in
  *":${INSTALL_DIR}:"*) ;;
  *)
    printf '\n  Note: %s is not on your PATH. Add it with:\n' "${INSTALL_DIR}"
    printf '    export PATH="%s:$PATH"\n' "${INSTALL_DIR}"
    ;;
esac

printf '\n    Try:   gecko <openapi-url>\n'
printf '    Docs:  %s\n\n' "${DOCS_URL}"
