#!/bin/bash
# Omnara CLI Installer (PRIMARY SOURCE)
# Usage: curl -fsSL https://omnara.com/install.sh | bash
#
# Environment variables:
#   OMNARA_INSTALL_DIR - Installation directory (default: ~/.omnara/bin)
#   OMNARA_APP_PATH    - macOS app bundle path (default: ~/.omnara/Omnara.app)
#   OMNARA_VERSION     - Specific version to install (default: latest)
#   OMNARA_ARCH        - Force architecture: 'x64' or 'arm64' (auto-detected by default)
#   OMNARA_NO_SERVICE  - Set to 1 to skip daemon service installation
#   OMNARA_RELEASE_URL - Override the release server base URL (default: https://releases.omnara.com)
#   PRERELEASE         - Set to 1 to install the prerelease version

set -euo pipefail

# Configuration
INSTALL_DIR="${OMNARA_INSTALL_DIR:-$HOME/.omnara/bin}"
APP_DEST="${OMNARA_APP_PATH:-$HOME/.omnara/Omnara.app}"
VERSION="${OMNARA_VERSION:-latest}"
PRERELEASE="${PRERELEASE:-0}"
BASE_URL="${OMNARA_RELEASE_URL:-https://releases.omnara.com}"
BASE_URL="${BASE_URL%/}"
BINARY_NAME="omnara"
SERVICE_NAME="com.omnara.daemon"
OMNARA_HOME="$HOME/.omnara"
POST_INSTALL_SHELL_REFRESH_COMMAND=""

# Colors (disabled if not a terminal)
if [ -t 1 ]; then
  RED='\033[0;31m'
  GREEN='\033[0;32m'
  YELLOW='\033[0;33m'
  BLUE='\033[0;34m'
  NC='\033[0m'
else
  RED=''
  GREEN=''
  YELLOW=''
  BLUE=''
  NC=''
fi

log() { echo -e "${BLUE}==>${NC} $1"; }
success() { echo -e "${GREEN}==>${NC} $1"; }
warn() { echo -e "${YELLOW}warning:${NC} $1"; }
error() { echo -e "${RED}error:${NC} $1" >&2; exit 1; }

# Run a command with a timeout (best-effort; returns command exit code or 124 on timeout)
run_with_timeout() {
  local timeout_s="$1"
  shift

  "$@" &
  local cmd_pid=$!

  (
    sleep "$timeout_s"
    if kill -0 "$cmd_pid" 2>/dev/null; then
      kill -TERM "$cmd_pid" 2>/dev/null || true
      sleep 1
      kill -KILL "$cmd_pid" 2>/dev/null || true
    fi
  ) &
  local watchdog_pid=$!

  local exit_code=0
  wait "$cmd_pid" 2>/dev/null || exit_code=$?
  kill -KILL "$watchdog_pid" 2>/dev/null || true
  wait "$watchdog_pid" 2>/dev/null || true

  # If the process was killed by the watchdog, use a conventional timeout code.
  if [ "$exit_code" -ge 128 ] 2>/dev/null; then
    exit_code=124
  fi

  return "$exit_code"
}

# Best-effort dependency installation (non-fatal and quiet)
install_dependencies() {
  # Avoid running Homebrew (or any interactive dependency install) in non-interactive
  # contexts like daemon auto-updates.
  if [ ! -t 1 ]; then
    return 0
  fi

  if [ "$(uname -s)" != "Darwin" ]; then
    return 0
  fi

  if ! command -v brew &>/dev/null; then
    return 0
  fi

  if command -v cloudflared &>/dev/null; then
    return 0
  fi

  log "Installing optional dependency: cloudflared..."

  # Run in background so the installer doesn't block.
  (
    run_with_timeout 60 env HOMEBREW_NO_AUTO_UPDATE=1 brew install cloudflared >/dev/null 2>&1 || true
  ) &
}

# Detect OS and architecture
detect_platform() {
  local os arch suffix=""

  case "$(uname -s)" in
    Darwin) os="darwin" ;;
    Linux)  os="linux" ;;
    MINGW*|MSYS*|CYGWIN*)
      error "Windows installs must use PowerShell: irm https://omnara.com/install.ps1 | iex"
      ;;
    *)      error "Unsupported OS: $(uname -s)" ;;
  esac

  # Allow manual architecture override via OMNARA_ARCH environment variable
  if [ -n "${OMNARA_ARCH:-}" ]; then
    case "${OMNARA_ARCH}" in
      x64|amd64|x86_64) arch="x64" ;;
      arm64|aarch64)    arch="arm64" ;;
      *)                error "Invalid OMNARA_ARCH value: ${OMNARA_ARCH}. Use 'x64' or 'arm64'" ;;
    esac
    log "Using manually specified architecture: ${arch}" >&2
  else
    case "$(uname -m)" in
      x86_64|amd64)  arch="x64" ;;
      arm64|aarch64) arch="arm64" ;;
      *)             error "Unsupported architecture: $(uname -m)" ;;
    esac

    # On macOS, detect Rosetta translation: if the current shell is x86_64 but
    # the hardware is actually Apple Silicon, prefer the native arm64 binary.
    if [ "$os" = "darwin" ] && [ "$arch" = "x64" ]; then
      if sysctl -n sysctl.proc_translated 2>/dev/null | grep -q '^1$'; then
        arch="arm64"
        log "Detected Rosetta translation; using native arm64 binary" >&2
      fi
    fi
  fi

  # Detect musl libc (Alpine Linux, etc.)
  if [ "$os" = "linux" ]; then
    if ldd --version 2>&1 | grep -qi musl; then
      suffix="-musl"
    fi
  fi

  echo "${os}-${arch}${suffix}"
}

# Check for required tools
check_requirements() {
  local missing=()

  if ! command -v curl &>/dev/null && ! command -v wget &>/dev/null; then
    missing+=("curl or wget")
  fi

  if [ ${#missing[@]} -ne 0 ]; then
    error "Missing required tools: ${missing[*]}"
  fi
}

# Download file with curl or wget
download() {
  local url="$1"
  local output="$2"

  if command -v curl &>/dev/null; then
    curl -fsSL "$url" -o "$output"
  else
    wget -q "$url" -O "$output"
  fi
}

# Get the download URL for the platform
get_download_url() {
  local platform="$1"
  local version="$2"
  local base_path=""
  local suffix=""

  # Use prerelease path if PRERELEASE=1
  if [ "$PRERELEASE" = "1" ]; then
    base_path="${BASE_URL}/prerelease"
  else
    base_path="${BASE_URL}"
  fi

  if [ "${3+x}" = "x" ]; then
    suffix="$3"
  else
    case "$platform" in
      darwin-*) suffix=".zip" ;;
      *)        suffix="" ;;
    esac
  fi

  if [ "$version" = "latest" ]; then
    echo "${base_path}/latest/omnara-${platform}${suffix}"
  else
    echo "${base_path}/${version}/omnara-${platform}${suffix}"
  fi
}

get_bundle_download_url() {
  local platform="$1"
  local version="$2"
  local base_path=""
  local artifact=""

  if [ "$PRERELEASE" = "1" ]; then
    base_path="${BASE_URL}/prerelease"
  else
    base_path="${BASE_URL}"
  fi

  case "$platform" in
    darwin-arm64|darwin-x64) artifact="omnara-${platform}-bundle.zip" ;;
    linux-x64|linux-arm64|linux-x64-musl) artifact="omnara-${platform}-bundle.tar.gz" ;;
    *) return 1 ;;
  esac

  echo "${base_path}/${version}/${artifact}"
}

# Helper to display path with ~ for home directory
tildify() {
  if [[ $1 == "$HOME"/* ]]; then
    echo "~${1#"$HOME"}"
  else
    echo "$1"
  fi
}

# Check if a config file is writable (or can be created)
is_writable_config() {
  local config_file="$1"
  # File exists and is writable
  if [[ -w $config_file ]]; then
    return 0
  fi
  # File doesn't exist, but parent directory is writable (we can create it)
  if [[ ! -e $config_file ]] && [[ -w $(dirname "$config_file") ]]; then
    return 0
  fi
  return 1
}

# Check if config already has omnara PATH setup
config_has_omnara() {
  local config_file="$1"
  if [[ -f $config_file ]] && grep -q "# omnara" "$config_file" 2>/dev/null; then
    return 0
  fi
  return 1
}

# Make omnara available on PATH.
#
# Strategy:
#   1. If ~/.local/bin is already on $PATH, symlink the binary there (no shell
#      config changes needed, no restart required).
#   2. Otherwise, auto-edit the user's shell config to add ~/.omnara/bin to PATH
#      and set POST_INSTALL_SHELL_REFRESH_COMMAND so the post-install output
#      tells them to restart their shell.
setup_path() {
  local local_bin="$HOME/.local/bin"
  local binary_name="$BINARY_NAME"

  # GitHub Actions support
  if [[ -n "${GITHUB_ACTIONS-}" ]] && [[ "${GITHUB_ACTIONS}" == "true" ]]; then
    echo "$INSTALL_DIR" >> "$GITHUB_PATH"
    log "Added $INSTALL_DIR to \$GITHUB_PATH"
    return
  fi

  # Fast path: symlink into ~/.local/bin if it's already on PATH
  if echo "$PATH" | tr ':' '\n' | grep -qx "$local_bin"; then
    if mkdir -p "$local_bin" 2>/dev/null && ln -snf "${INSTALL_DIR}/${binary_name}" "${local_bin}/${binary_name}" 2>/dev/null; then
      success "Symlinked ${binary_name} into ${local_bin}"
      return
    fi
    warn "Could not symlink into ${local_bin}, falling back to shell config"
  fi

  # Slow path: auto-edit shell config to add ~/.omnara/bin to PATH
  local tilde_bin_dir
  tilde_bin_dir=$(tildify "$INSTALL_DIR")

  local current_shell
  current_shell=$(basename "$SHELL")

  case $current_shell in
    fish)
      local fish_config="$HOME/.config/fish/config.fish"
      local tilde_fish_config
      tilde_fish_config=$(tildify "$fish_config")

      if config_has_omnara "$fish_config"; then
        log "PATH already configured in \"$tilde_fish_config\""
        POST_INSTALL_SHELL_REFRESH_COMMAND="source $tilde_fish_config"
      elif is_writable_config "$fish_config"; then
        mkdir -p "$(dirname "$fish_config")"
        {
          echo -e '\n# omnara'
          echo "fish_add_path $INSTALL_DIR"
        } >> "$fish_config"
        log "Added \"$tilde_bin_dir\" to \$PATH in \"$tilde_fish_config\""
        POST_INSTALL_SHELL_REFRESH_COMMAND="source $tilde_fish_config"
      else
        warn "Manually add the directory to $tilde_fish_config (or similar):"
        echo "  fish_add_path $INSTALL_DIR"
      fi
      ;;

    zsh)
      local zsh_config="$HOME/.zshrc"
      local tilde_zsh_config
      tilde_zsh_config=$(tildify "$zsh_config")

      if config_has_omnara "$zsh_config"; then
        log "PATH already configured in \"$tilde_zsh_config\""
        POST_INSTALL_SHELL_REFRESH_COMMAND="source $tilde_zsh_config"
      elif is_writable_config "$zsh_config"; then
        {
          echo -e '\n# omnara'
          echo "path=(\"$INSTALL_DIR\" \$path)"
        } >> "$zsh_config"
        log "Added \"$tilde_bin_dir\" to \$PATH in \"$tilde_zsh_config\""
        POST_INSTALL_SHELL_REFRESH_COMMAND="source $tilde_zsh_config"
      else
        warn "Manually add the directory to $tilde_zsh_config (or similar):"
        echo "  path=(\"$tilde_bin_dir\" \$path)"
      fi
      ;;

    bash)
      local bash_configs=(
        "$HOME/.bashrc"
        "$HOME/.bash_profile"
        "$HOME/.profile"
      )

      if [[ ${XDG_CONFIG_HOME:-} ]]; then
        bash_configs+=(
          "$XDG_CONFIG_HOME/.bashrc"
          "$XDG_CONFIG_HOME/.bash_profile"
          "$XDG_CONFIG_HOME/bashrc"
          "$XDG_CONFIG_HOME/bash_profile"
        )
      fi

      local set_manually=true
      for bash_config in "${bash_configs[@]}"; do
        local tilde_bash_config
        tilde_bash_config=$(tildify "$bash_config")

        if config_has_omnara "$bash_config"; then
          log "PATH already configured in \"$tilde_bash_config\""
          POST_INSTALL_SHELL_REFRESH_COMMAND="source $tilde_bash_config"
          set_manually=false
          break
        elif is_writable_config "$bash_config"; then
          {
            echo -e '\n# omnara'
            echo "export PATH=\"$INSTALL_DIR:\$PATH\""
          } >> "$bash_config"
          log "Added \"$tilde_bin_dir\" to \$PATH in \"$tilde_bash_config\""
          POST_INSTALL_SHELL_REFRESH_COMMAND="source $tilde_bash_config"
          set_manually=false
          break
        fi
      done

      if [[ $set_manually = true ]]; then
        warn "Manually add the directory to ~/.bashrc (or similar):"
        echo "  export PATH=\"$tilde_bin_dir:\$PATH\""
      fi
      ;;

    *)
      warn "Manually add the directory to your shell config:"
      echo "  export PATH=\"$tilde_bin_dir:\$PATH\""
      ;;
  esac
}

# Install launchd service (macOS)
install_launchd_service() {
  local binary_path="$1"
  local plist_path="$HOME/Library/LaunchAgents/${SERVICE_NAME}.plist"
  local log_path="${OMNARA_HOME}/logs/daemon/daemon.log"
  local associated_bundle_id="com.omnara.cli"
  local service_binary_path="$binary_path"

  if [[ -L "$binary_path" ]]; then
    local symlink_target
    symlink_target=$(readlink "$binary_path" 2>/dev/null || true)
    if [[ "$symlink_target" == "$APP_DEST/Contents/MacOS/omnara" ]]; then
      service_binary_path="$APP_DEST/Contents/MacOS/omnara"
    fi
  fi

  log "Setting up launchd service for auto-start..."

  # Create directories
  mkdir -p "$(dirname "$plist_path")"
  mkdir -p "$(dirname "$log_path")"

  # Associate the launchd job with the app bundle so it shows up correctly in
  # System Settings -> Login Items.
  if [[ -f "$APP_DEST/Contents/Info.plist" ]] && [[ -x "/usr/libexec/PlistBuddy" ]]; then
    local detected_bundle_id
    detected_bundle_id=$(
      /usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$APP_DEST/Contents/Info.plist" 2>/dev/null || true
    )
    if [[ -n "$detected_bundle_id" ]]; then
      associated_bundle_id="$detected_bundle_id"
    fi
  fi

  # Unload existing service if present
  if [ -f "$plist_path" ]; then
    launchctl unload "$plist_path" 2>/dev/null || true
  fi

  # Create plist file
  # Note: EnvironmentVariables can be overridden by creating a file at
  # ~/.omnara/daemon.env with KEY=VALUE pairs (one per line)
  cat > "$plist_path" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>${SERVICE_NAME}</string>

    <key>AssociatedBundleIdentifiers</key>
    <array>
        <string>${associated_bundle_id}</string>
    </array>

    <key>ProgramArguments</key>
    <array>
        <string>${service_binary_path}</string>
        <string>daemon</string>
        <string>run-service</string>
    </array>

    <key>EnvironmentVariables</key>
    <dict>
        <key>HOME</key>
        <string>${HOME}</string>
        <key>PATH</key>
        <string>${INSTALL_DIR}:${PATH}</string>
    </dict>

    <key>RunAtLoad</key>
    <true/>

    <key>KeepAlive</key>
    <dict>
        <key>SuccessfulExit</key>
        <false/>
        <key>Crashed</key>
        <true/>
    </dict>

    <key>ThrottleInterval</key>
    <integer>5</integer>

    <key>StandardOutPath</key>
    <string>${log_path}</string>

    <key>StandardErrorPath</key>
    <string>${log_path}</string>

    <key>WorkingDirectory</key>
    <string>${HOME}</string>
</dict>
</plist>
EOF

  # Load the service
  if ! launchctl load "$plist_path" 2>/dev/null; then
    warn "Could not set up daemon auto-start (launchd service failed to load)."
    warn "Omnara won't automatically launch on boot, but you can still"
    warn "start sessions by running 'omnara' in your terminal."
    return
  fi

  success "Daemon service installed and started"
  log "  Config: $plist_path"
  log "  Logs:   $log_path"
}

# Install systemd service (Linux)
ensure_systemd_killmode_dropin() {
  if [ "$(uname -s)" != "Linux" ]; then
    return 0
  fi

  if ! command -v systemctl &>/dev/null; then
    return 0
  fi

  local dropin_dir="$HOME/.config/systemd/user/${SERVICE_NAME}.service.d"
  local dropin_path="$dropin_dir/killmode.conf"

  if ! mkdir -p "$dropin_dir" 2>/dev/null; then
    return 0
  fi

  if ! cat > "$dropin_path" << EOF
[Service]
KillMode=process
EOF
  then
    return 0
  fi

  run_with_timeout 10 systemctl --user daemon-reload >/dev/null 2>&1 || true
}

install_systemd_service() {
  local binary_path="$1"
  local service_path="$HOME/.config/systemd/user/${SERVICE_NAME}.service"
  local log_path="${OMNARA_HOME}/logs/daemon/daemon.log"

  log "Setting up systemd user service for auto-start..."

  # Create directories
  mkdir -p "$(dirname "$service_path")"
  mkdir -p "$(dirname "$log_path")"

  # Stop existing service if running
  systemctl --user stop "$SERVICE_NAME" 2>/dev/null || true

  # Create service file
  cat > "$service_path" << EOF
[Unit]
Description=Omnara CLI Background Daemon
After=network.target

[Service]
Type=simple
ExecStart=${binary_path} daemon run-service
Restart=on-failure
RestartSec=5
KillMode=process
StandardOutput=append:${log_path}
StandardError=append:${log_path}
WorkingDirectory=${HOME}
Environment="PATH=${INSTALL_DIR}:${PATH}"

[Install]
WantedBy=default.target
EOF

  # Reload systemd and enable/start service (subshell so set -e doesn't abort the installer)
  if ! (
    systemctl --user daemon-reload
    systemctl --user enable "$SERVICE_NAME"
    systemctl --user start "$SERVICE_NAME"
  ) 2>/dev/null; then
    warn "Could not set up daemon auto-start (systemd may not be available)."
    warn "Omnara won't automatically launch on boot, but you can still"
    warn "start sessions by running 'omnara' in your terminal."
    return
  fi

  # Try to enable lingering (requires sudo)
  if command -v loginctl &>/dev/null; then
    if loginctl enable-linger "$USER" 2>/dev/null; then
      log "Enabled lingering for user services at boot"
    else
      warn "Run 'sudo loginctl enable-linger $USER' to start daemon at system boot"
    fi
  fi

  success "Daemon service installed and started"
  log "  Config: $service_path"
  log "  Logs:   $log_path"
  log "  Status: systemctl --user status $SERVICE_NAME"
}

# Install daemon service based on OS
install_daemon_service() {
  local binary_path="$1"

  if [ "${OMNARA_NO_SERVICE:-}" = "1" ]; then
    ensure_systemd_killmode_dropin
    log "Skipping daemon service installation (OMNARA_NO_SERVICE=1)"
    return
  fi

  case "$(uname -s)" in
    Darwin)
      install_launchd_service "$binary_path"
      ;;
    Linux)
      if command -v systemctl &>/dev/null; then
        install_systemd_service "$binary_path"
      else
        warn "Could not set up daemon auto-start (systemd not found)."
        warn "Omnara won't automatically launch on boot, but you can still"
        warn "start sessions by running 'omnara' in your terminal."
      fi
      ;;
    *)
      warn "Could not set up daemon auto-start (unsupported platform)."
      warn "Omnara won't automatically launch on boot, but you can still"
      warn "start sessions by running 'omnara' in your terminal."
      ;;
  esac
}

install_bundle_artifact() {
  local platform="$1"
  local url="$2"
  local binary_path="$3"
  local tmp_dir
  tmp_dir=$(mktemp -d)

  local artifact="$tmp_dir/bundle"
  log "Downloading bundled artifact from: ${url}"
  if ! download "$url" "$artifact"; then
    rm -rf "$tmp_dir"
    warn "Failed to download bundled Omnara CLI"
    return 1
  fi

  mkdir -p "$INSTALL_DIR"

  if [[ "$platform" == darwin-* ]]; then
    mkdir -p "$tmp_dir/unzip"
    if ! /usr/bin/ditto -xk "$artifact" "$tmp_dir/unzip"; then
      rm -rf "$tmp_dir"
      warn "Failed to extract bundled Omnara app"
      return 1
    fi

    local app_src
    app_src=$(find "$tmp_dir/unzip" -maxdepth 2 -name "Omnara*.app" | head -n 1)
    if [[ -z "$app_src" ]]; then
      rm -rf "$tmp_dir"
      warn "Bundled Omnara app bundle not found in zip"
      return 1
    fi

    local app_binary="$app_src/Contents/MacOS/omnara"
    local claude_src="$app_src/Contents/Resources/bin/omnara-claude"
    local codex_src="$app_src/Contents/Resources/bin/omnara-codex"
    if [[ ! -x "$app_binary" || ! -x "$claude_src" || ! -x "$codex_src" ]]; then
      rm -rf "$tmp_dir"
      warn "Bundled Omnara app is missing required executables"
      return 1
    fi

    mkdir -p "$(dirname "$APP_DEST")"
    rm -rf "$APP_DEST"
    if ! mv "$app_src" "$APP_DEST"; then
      rm -rf "$tmp_dir"
      warn "Failed to install bundled Omnara app"
      return 1
    fi

    local claude_dst="${INSTALL_DIR}/omnara-claude"
    local codex_dst="${INSTALL_DIR}/omnara-codex"
    local claude_tmp="${claude_dst}.tmp.$$"
    local codex_tmp="${codex_dst}.tmp.$$"
    local claude_prev="${claude_dst}.prev.$$"
    local codex_prev="${codex_dst}.prev.$$"
    rm -f "$claude_tmp" "$codex_tmp" "$claude_prev" "$codex_prev"

    if [[ -e "$claude_dst" ]] && ! mv "$claude_dst" "$claude_prev"; then
      rm -rf "$tmp_dir"
      warn "Failed to prepare existing Claude Code provider for replacement"
      return 1
    fi
    if [[ -e "$codex_dst" ]] && ! mv "$codex_dst" "$codex_prev"; then
      if [[ -e "$claude_prev" ]]; then
        mv "$claude_prev" "$claude_dst" 2>/dev/null || true
      fi
      rm -rf "$tmp_dir"
      warn "Failed to prepare existing Codex provider for replacement"
      return 1
    fi

    if ! ln -snf "$APP_DEST/Contents/MacOS/omnara" "$binary_path" ||
       ! cp "$APP_DEST/Contents/Resources/bin/omnara-claude" "$claude_tmp" ||
       ! cp "$APP_DEST/Contents/Resources/bin/omnara-codex" "$codex_tmp" ||
       ! chmod +x "$APP_DEST/Contents/MacOS/omnara" "$claude_tmp" "$codex_tmp" ||
       ! mv -f "$claude_tmp" "$claude_dst" ||
       ! mv -f "$codex_tmp" "$codex_dst" ||
       ! run_with_timeout 20 "$claude_dst" --version >/dev/null 2>&1 ||
       ! run_with_timeout 20 "$codex_dst" --version >/dev/null 2>&1; then
      rm -f "$claude_tmp" "$codex_tmp"
      rm -f "$claude_dst" "$codex_dst"
      if [[ -e "$claude_prev" ]]; then
        mv "$claude_prev" "$claude_dst" 2>/dev/null || true
      fi
      if [[ -e "$codex_prev" ]]; then
        mv "$codex_prev" "$codex_dst" 2>/dev/null || true
      fi
      rm -rf "$tmp_dir"
      warn "Failed to install bundled Omnara provider tools"
      return 1
    fi
    rm -f "$claude_prev" "$codex_prev"

  else
    mkdir -p "$tmp_dir/extract"
    if ! tar xzf "$artifact" -C "$tmp_dir/extract"; then
      rm -rf "$tmp_dir"
      warn "Failed to extract bundled Omnara archive"
      return 1
    fi

    local omnara_src="$tmp_dir/extract/omnara"
    local claude_src="$tmp_dir/extract/omnara-claude"
    local codex_src="$tmp_dir/extract/omnara-codex"
    if [[ ! -x "$omnara_src" || ! -x "$claude_src" || ! -x "$codex_src" ]]; then
      rm -rf "$tmp_dir"
      warn "Bundled Omnara archive is missing required executables"
      return 1
    fi

    local claude_dst="${INSTALL_DIR}/omnara-claude"
    local codex_dst="${INSTALL_DIR}/omnara-codex"
    local claude_prev="${claude_dst}.prev.$$"
    local codex_prev="${codex_dst}.prev.$$"
    rm -f "$claude_prev" "$codex_prev"

    if [[ -e "$claude_dst" ]] && ! mv "$claude_dst" "$claude_prev"; then
      rm -rf "$tmp_dir"
      warn "Failed to prepare existing Claude Code provider for replacement"
      return 1
    fi
    if [[ -e "$codex_dst" ]] && ! mv "$codex_dst" "$codex_prev"; then
      if [[ -e "$claude_prev" ]]; then
        mv "$claude_prev" "$claude_dst" 2>/dev/null || true
      fi
      rm -rf "$tmp_dir"
      warn "Failed to prepare existing Codex provider for replacement"
      return 1
    fi

    if ! mv "$omnara_src" "$binary_path" ||
       ! mv "$claude_src" "$claude_dst" ||
       ! mv "$codex_src" "$codex_dst"; then
      rm -f "$claude_dst" "$codex_dst"
      if [[ -e "$claude_prev" ]]; then
        mv "$claude_prev" "$claude_dst" 2>/dev/null || true
      fi
      if [[ -e "$codex_prev" ]]; then
        mv "$codex_prev" "$codex_dst" 2>/dev/null || true
      fi
      rm -rf "$tmp_dir"
      warn "Failed to install bundled Omnara CLI"
      return 1
    fi

    if ! chmod +x "$binary_path" "$claude_dst" "$codex_dst" ||
       ! run_with_timeout 20 "$claude_dst" --version >/dev/null 2>&1 ||
       ! run_with_timeout 20 "$codex_dst" --version >/dev/null 2>&1; then
      rm -f "$claude_dst" "$codex_dst"
      if [[ -e "$claude_prev" ]]; then
        mv "$claude_prev" "$claude_dst" 2>/dev/null || true
      fi
      if [[ -e "$codex_prev" ]]; then
        mv "$codex_prev" "$codex_dst" 2>/dev/null || true
      fi
      rm -rf "$tmp_dir"
      warn "Failed to set executable bits on bundled Omnara CLI"
      return 1
    fi
    rm -f "$claude_prev" "$codex_prev"
  fi

  rm -rf "$tmp_dir"
  return 0
}

main() {
  echo ""
  if [ "$PRERELEASE" = "1" ]; then
    echo "  Omnara CLI Installer (PRERELEASE)"
  else
    echo "  Omnara CLI Installer"
  fi
  echo ""

  check_requirements
  install_dependencies

  local platform
  platform=$(detect_platform)
  log "Detected platform: ${platform}"

  local download_url
  download_url=$(get_download_url "$platform" "$VERSION")

  # Force uninstall existing omnara packages
  log "Checking for existing omnara installations..."

  # Uninstall Homebrew formula/cask if it exists
  if command -v brew &>/dev/null; then
    if brew list --formula omnara &>/dev/null 2>&1; then
      log "Uninstalling existing Homebrew formula..."
      run_with_timeout 60 env HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall --formula omnara >/dev/null 2>&1 || true
    fi
    if brew list --cask omnara &>/dev/null 2>&1; then
      log "Uninstalling existing Homebrew cask..."
      run_with_timeout 60 env HOMEBREW_NO_AUTO_UPDATE=1 brew uninstall --cask omnara >/dev/null 2>&1 || true
    fi
  fi

  # Uninstall npm package if it exists
  if command -v npm &>/dev/null; then
    if npm list -g omnara &>/dev/null 2>&1; then
      log "Uninstalling existing npm package..."
      npm uninstall -g omnara 2>/dev/null || true
    fi
  fi

  # Uninstall pip packages if they exist (check both pip and pip3)
  local pip_cmds=()
  if command -v pip &>/dev/null; then
    pip_cmds+=("pip")
  fi
  if command -v pip3 &>/dev/null; then
    pip_cmds+=("pip3")
  fi
  if [ ${#pip_cmds[@]} -gt 0 ]; then
    local pip_cmd
    for pip_cmd in "${pip_cmds[@]}"; do
      # On macOS, /usr/bin/pip* are CLT shims that trigger the Xcode CLT dialog
      if [ "$(uname -s)" = "Darwin" ] && [[ "$(command -v "$pip_cmd")" == /usr/bin/* ]]; then
        continue
      fi
      if $pip_cmd show omnara &>/dev/null 2>&1; then
        log "Uninstalling existing pip package via ${pip_cmd}..."
        $pip_cmd uninstall -y omnara 2>/dev/null || true
      fi
    done
  fi

  # Create install directory
  mkdir -p "$INSTALL_DIR"

  # Create omnara home directory
  mkdir -p "$OMNARA_HOME"
  chmod 700 "$OMNARA_HOME"

  local binary_path="${INSTALL_DIR}/${BINARY_NAME}"
  local installed_from_bundle=0
  local bundle_url=""

  if bundle_url=$(get_bundle_download_url "$platform" "$VERSION"); then
    if install_bundle_artifact "$platform" "$bundle_url" "$binary_path"; then
      installed_from_bundle=1
    else
      warn "Bundled install failed; falling back to legacy Omnara artifact."
    fi
  fi

  if [[ "$installed_from_bundle" -eq 0 && "$platform" == darwin-* ]]; then

    # macOS: download app bundle zip, unpack, symlink CLI
    local tmp_dir
    tmp_dir=$(mktemp -d)
    trap "rm -rf '$tmp_dir' 2>/dev/null || true" EXIT
    local use_app_bundle=1

    log "Downloading from: ${download_url}"
    if ! download "$download_url" "$tmp_dir/omnara.zip"; then
      warn "Zip download failed; attempting legacy binary."
      local fallback_url
      fallback_url=$(get_download_url "$platform" "$VERSION" "")
      log "Downloading from: ${fallback_url}"
      use_app_bundle=0
      if ! download "$fallback_url" "$tmp_dir/omnara"; then
        error "Failed to download Omnara CLI (zip or raw binary)"
      fi
    fi

    if [ "$use_app_bundle" -eq 1 ]; then
      mkdir -p "$tmp_dir/unzip"
      /usr/bin/ditto -xk "$tmp_dir/omnara.zip" "$tmp_dir/unzip"

      local app_src
      app_src=$(find "$tmp_dir/unzip" -maxdepth 2 -name "Omnara*.app" | head -n 1)
      if [[ -z "$app_src" ]]; then
        error "Downloaded app bundle not found in zip"
      fi

      mkdir -p "$(dirname "$APP_DEST")"
      local app_backup="${APP_DEST}.bak"
      rm -rf "$app_backup"
      if [ -e "$APP_DEST" ]; then
        mv "$APP_DEST" "$app_backup"
      fi
      if ! mv "$app_src" "$APP_DEST"; then
        if [ -e "$app_backup" ]; then
          mv "$app_backup" "$APP_DEST" || true
        fi
        error "Failed to install Omnara app bundle"
      fi

      mkdir -p "$INSTALL_DIR"
      ln -snf "$APP_DEST/Contents/MacOS/omnara" "$binary_path"
      chmod +x "$APP_DEST/Contents/MacOS/omnara"
      if [ -e "$app_backup" ]; then
        rm -rf "$app_backup" 2>/dev/null || true
      fi
    else
      mkdir -p "$INSTALL_DIR"
      mv "$tmp_dir/omnara" "$binary_path"
      chmod +x "$binary_path"
    fi

  elif [[ "$installed_from_bundle" -eq 0 ]]; then
    # Non-macOS: download raw binary
    local tmp_file
    tmp_file=$(mktemp)
    trap 'rm -f "$tmp_file" 2>/dev/null || true' EXIT

    log "Downloading from: ${download_url}"
    if ! download "$download_url" "$tmp_file"; then
      error "Failed to download Omnara CLI"
    fi

    mkdir -p "$INSTALL_DIR"
    mv "$tmp_file" "$binary_path"
    chmod +x "$binary_path"

    trap - EXIT
  fi

  # Setup PATH
  setup_path

  # Verify installation
  if OMNARA_NO_UPDATE=1 "$binary_path" --version &>/dev/null; then
    success "Omnara CLI installed successfully!"
    echo ""
    echo "  Location: ${binary_path}"
    echo "  Version:  $(OMNARA_NO_UPDATE=1 "$binary_path" --version 2>/dev/null | tail -1)"
    echo ""

    # Install daemon service
    install_daemon_service "$binary_path"

    echo ""
    if [[ -n "${POST_INSTALL_SHELL_REFRESH_COMMAND:-}" ]]; then
      echo -e "  ${YELLOW}============================================${NC}"
      echo -e "  ${YELLOW}IMPORTANT:${NC} To use omnara, do ${YELLOW}one${NC} of these:"
      echo ""
      echo -e "    ${GREEN}1.${NC} Open a new terminal window"
      echo ""
      echo -e "    ${GREEN}2.${NC} Or run:  ${GREEN}${POST_INSTALL_SHELL_REFRESH_COMMAND}${NC}"
      echo -e "  ${YELLOW}============================================${NC}"
      echo ""
      log "Then, in a git repository, run:"
      echo ""
      echo -e "    ${GREEN}omnara${NC}"
      echo ""
    else
      log "To get started, in a git repository, run:"
      echo ""
      echo -e "    ${GREEN}omnara${NC}"
      echo ""
    fi
  else
    error "Installation verification failed"
  fi
}

main "$@"
