#!/usr/bin/env bash
# bootstrap-dev-env - provider-agnostic Kandev development environment setup.
#
# Cloud executor prepare scripts should handle provider concerns first:
# authentication, clone/checkout, workspace placement, and agentctl startup.
# After cloning, call this script from the repo root to install the Kandev
# toolchain and dependencies consistently across Sprites, Daytona, Modal,
# Codespaces, local VMs, and similar environments.
#
# Usage:
#   scripts/bootstrap-dev-env [options]
#
# Options:
#   --with-e2e              Install Playwright browser/system deps for E2E
#   --without-hooks         Skip pre-commit hook wiring
#   --without-node-modules  Skip pnpm install
#   --without-os-packages   Skip best-effort OS package installation
#   --without-mise-install  Require mise to already be installed
#   --provider NAME         Record caller/provider name in logs only
#   -h, --help              Show this help

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

WITH_E2E=0
WITH_HOOKS=1
WITH_NODE_MODULES=1
WITH_OS_PACKAGES=1
WITH_MISE_INSTALL=1
PROVIDER="generic"

usage() {
  awk 'NR > 1 { if ($0 !~ /^#/) exit; sub(/^# ?/, ""); print }' "$0"
  exit "${1:-2}"
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --with-e2e) WITH_E2E=1; shift ;;
    --without-hooks) WITH_HOOKS=0; shift ;;
    --without-node-modules) WITH_NODE_MODULES=0; shift ;;
    --without-os-packages) WITH_OS_PACKAGES=0; shift ;;
    --without-mise-install) WITH_MISE_INSTALL=0; shift ;;
    --provider) PROVIDER="${2:?--provider requires a value}"; shift 2 ;;
    -h|--help) usage 0 ;;
    *) echo "bootstrap-dev-env: unknown argument '$1'" >&2; usage 2 ;;
  esac
done

log() { printf '[bootstrap:%s] %s\n' "$PROVIDER" "$*" >&2; }
warn() { printf '[bootstrap:%s] warning: %s\n' "$PROVIDER" "$*" >&2; }
die() { printf '[bootstrap:%s] error: %s\n' "$PROVIDER" "$*" >&2; exit 1; }

run_privileged() {
  if [[ "${EUID:-$(id -u)}" -eq 0 ]]; then
    "$@"
  elif command -v sudo >/dev/null 2>&1; then
    sudo "$@"
  else
    return 127
  fi
}

install_os_packages() {
  [[ "$WITH_OS_PACKAGES" -eq 1 ]] || { log "skipping OS packages"; return 0; }

  if command -v apt-get >/dev/null 2>&1; then
    log "installing OS packages with apt-get"
    if ! run_privileged apt-get update; then
      warn "apt-get requires root/sudo; skipping OS package installation"
      return 0
    fi
    run_privileged env DEBIAN_FRONTEND=noninteractive apt-get install -y \
      bash build-essential ca-certificates curl file git gzip lsof make openssh-client \
      pipx pkg-config python3 python3-pip rsync sqlite3 tar unzip xz-utils zip \
      libsqlite3-dev || warn "apt-get package installation failed; continuing because packages may already be present"
    return 0
  fi

  if command -v dnf >/dev/null 2>&1; then
    log "installing OS packages with dnf"
    run_privileged dnf install -y \
      bash ca-certificates curl file gcc gcc-c++ git gzip lsof make openssh-clients \
      pipx pkgconf-pkg-config python3 python3-pip rsync sqlite sqlite-devel tar unzip xz zip \
      || warn "dnf package installation failed; continuing because packages may already be present"
    return 0
  fi

  if command -v apk >/dev/null 2>&1; then
    log "installing OS packages with apk"
    run_privileged apk add --no-cache \
      bash build-base ca-certificates curl file git gzip lsof make openssh-client \
      pipx pkgconf python3 py3-pip rsync sqlite sqlite-dev tar unzip xz zip \
      || warn "apk package installation failed; continuing because packages may already be present"
    return 0
  fi

  if command -v brew >/dev/null 2>&1; then
    log "installing OS packages with Homebrew"
    brew install bash ca-certificates curl file git lsof make openssh pipx pkg-config \
      python rsync sqlite unzip xz zip \
      || warn "Homebrew package installation failed; continuing because packages may already be present"
    return 0
  fi

  warn "no supported package manager found; install build tools, sqlite headers, unzip, pipx, and OpenSSH manually if needed"
}

install_mise() {
  if command -v mise >/dev/null 2>&1; then
    log "mise already installed: $(mise --version 2>/dev/null || true)"
    persist_mise_activation
    return 0
  fi

  [[ "$WITH_MISE_INSTALL" -eq 1 ]] || die "mise is not installed and --without-mise-install was passed"
  command -v curl >/dev/null 2>&1 || die "curl is required to install mise"

  log "installing mise"
  tmp_mise_script="$(mktemp)"
  trap 'rm -f "$tmp_mise_script"' EXIT
  curl -fsSL https://mise.run -o "$tmp_mise_script"
  sh "$tmp_mise_script"
  export PATH="$HOME/.local/bin:$PATH"
  command -v mise >/dev/null 2>&1 || die "mise install finished but mise is not on PATH"
  persist_mise_activation
}

persist_mise_activation() {
  [[ -n "${HOME:-}" ]] || return 0
  local bashrc="$HOME/.bashrc"

  touch "$bashrc"
  grep -Fqx 'export PATH="$HOME/.local/bin:$PATH"' "$bashrc" 2>/dev/null \
    || printf '\nexport PATH="$HOME/.local/bin:$PATH"\n' >> "$bashrc"
  grep -Fqx 'eval "$(mise activate bash)"' "$bashrc" 2>/dev/null \
    || printf 'eval "$(mise activate bash)"\n' >> "$bashrc"
}

activate_mise() {
  export PATH="$HOME/.local/bin:$PATH"
  cd "$REPO_ROOT"

  [[ -f "$REPO_ROOT/mise.toml" ]] || die "missing mise.toml at repo root"

  log "trusting mise.toml"
  mise trust "$REPO_ROOT/mise.toml" >/dev/null 2>&1 || mise trust >/dev/null

  log "installing mise tools"
  mise install

  log "activating mise environment for bootstrap"
  eval "$(mise activate bash)"
}

install_node_modules() {
  [[ "$WITH_NODE_MODULES" -eq 1 ]] || { log "skipping pnpm install"; return 0; }
  log "installing pnpm workspace dependencies"
  cd "$REPO_ROOT/apps"
  pnpm install --frozen-lockfile
}

install_hooks() {
  [[ "$WITH_HOOKS" -eq 1 ]] || { log "skipping git hook setup"; return 0; }
  log "wiring pre-commit hooks"
  cd "$REPO_ROOT"
  make doctor
}

install_e2e() {
  [[ "$WITH_E2E" -eq 1 ]] || { log "skipping Playwright E2E browser setup"; return 0; }
  log "installing Playwright Chromium browser/deps"
  "$REPO_ROOT/scripts/install-playwright-browsers.sh"
}

main() {
  cd "$REPO_ROOT"
  log "bootstrapping Kandev development environment at $REPO_ROOT"
  install_os_packages
  install_mise
  activate_mise
  install_node_modules
  install_hooks
  install_e2e
  log "bootstrap complete"
}

main
