#!/usr/bin/env sh
# Install the Flow CLI from the packed npm tarball.
#
# Usage:
#   curl -fsSL https://flow.pixelbrain.cz/install-cli.sh | sh
#
# Environment overrides:
#   FLOW_VERSION       Pin the expected version (e.g. "0.5.0"). The installer
#                      verifies that the downloaded tarball matches it.
#   FLOW_INSTALL_DIR   Install directory. Defaults to /usr/local/bin (uses
#                      sudo if not writable).
#   FLOW_CLI_BASE_URL  Base URL for the CLI tarball. Defaults to
#                      https://flow.pixelbrain.cz.

set -eu

BASE_URL="${FLOW_CLI_BASE_URL:-https://flow.pixelbrain.cz}"
BASE_URL="${BASE_URL%/}"
REQUESTED_INSTALL_DIR="${FLOW_INSTALL_DIR:-/usr/local/bin}"
BIN_NAME="flow"

# Colorize log levels only when stdout is a terminal; stay plain for piped
# output and CI logs.
if [ -t 1 ]; then
  C_INFO='\033[0;36m'
  C_OK='\033[0;32m'
  C_ERR='\033[0;31m'
  C_LOGO='\033[1;35m'
  C_RST='\033[0m'
else
  C_INFO=''
  C_OK=''
  C_ERR=''
  C_LOGO=''
  C_RST=''
fi

banner() {
  printf "%b" "$C_LOGO"
  cat <<'EOF'


    ________
   / ____/ /___ _      __
  / /_  / / __ \ | /| / /
 / __/ / / /_/ / |/ |/ /
/_/   /_/\____/|__/|__/
        process flow for agents


EOF
  printf "%b" "$C_RST"
}

info() {
  printf "${C_INFO}[INFO]${C_RST} %s\n" "$1"
}

success() {
  printf "${C_OK}[SUCCESS]${C_RST} %s\n" "$1"
}

err() {
  printf "${C_ERR}[ERROR]${C_RST} %s\n" "$1" >&2
  exit 1
}

require_cmd() {
  command -v "$1" >/dev/null 2>&1 || err "$1 is required to install the Flow CLI"
}

banner

# Detect OS.
uname_s=$(uname -s)
case "$uname_s" in
  Linux*)  os="linux" ;;
  Darwin*) os="darwin" ;;
  *) err "unsupported OS: $uname_s (supported: Linux, Darwin)" ;;
esac

# Detect architecture.
uname_m=$(uname -m)
case "$uname_m" in
  x86_64|amd64) arch="x64" ;;
  arm64|aarch64) arch="arm64" ;;
  *) err "unsupported architecture: $uname_m (supported: x86_64, arm64)" ;;
esac

require_cmd curl
require_cmd node
require_cmd npm

# Resolve npm now: sudo runs under secure_path, which usually misses
# user-local installs (nvm, asdf).
npm_cmd=$(command -v npm)

# Resolve the requested version. The distribution endpoint serves a packed
# npm tarball; FLOW_VERSION pins the expected package version inside it.
if [ -n "${FLOW_VERSION:-}" ]; then
  version="${FLOW_VERSION#v}"
else
  version="latest"
fi

url="${BASE_URL}/cli/flow-cli-latest.tgz"

# npm installs global binaries under <prefix>/bin. The default Flow install
# dir is that bin directory; custom bin-like paths keep the same behavior.
case "$REQUESTED_INSTALL_DIR" in
  */bin) npm_prefix="${REQUESTED_INSTALL_DIR%/bin}" ;;
  *) npm_prefix="$REQUESTED_INSTALL_DIR" ;;
esac

bin_dir="${npm_prefix}/bin"
dest="${bin_dir}/${BIN_NAME}"

info "Platform: ${os}-${arch}"
info "Install dir: ${bin_dir}"
info "Version: ${version}"

tmp=$(mktemp -d)
trap 'rm -rf "$tmp"' EXIT
tarball="${tmp}/flow-cli.tgz"

info "Downloading Flow CLI..."
curl -fsSL --retry 3 -o "$tarball" "$url" || err "failed to download from $url"

# Create the npm prefix and bin directory if missing. Fall back to sudo when
# the target is not writable (e.g. /usr/local on a fresh machine).
if [ ! -d "$npm_prefix" ]; then
  info "Creating npm prefix ${npm_prefix}"
  if ! mkdir -p "$npm_prefix" 2>/dev/null; then
    require_cmd sudo
    info "${npm_prefix} could not be created; using sudo"
    sudo mkdir -p "$npm_prefix" || err "failed to create npm prefix: ${npm_prefix}"
  fi
fi

if [ ! -d "$bin_dir" ]; then
  info "Creating install directory ${bin_dir}"
  if ! mkdir -p "$bin_dir" 2>/dev/null; then
    require_cmd sudo
    info "${bin_dir} could not be created; using sudo"
    sudo mkdir -p "$bin_dir" || err "failed to create install directory: ${bin_dir}"
  fi
fi

info "Installing @flow/cli to ${dest}"

if [ -w "$npm_prefix" ] && [ -w "$bin_dir" ]; then
  npm install -g --prefix "$npm_prefix" "$tarball" >/dev/null
else
  require_cmd sudo
  info "${npm_prefix} is not writable; using sudo"
  sudo env "PATH=$PATH" "$npm_cmd" install -g --prefix "$npm_prefix" "$tarball" >/dev/null
fi

if [ "$version" != "latest" ]; then
  actual_version=$(PATH="${bin_dir}:$PATH" "$BIN_NAME" --version 2>/dev/null | awk 'NR == 1 { print $NF }') || err "installed binary failed to report a version"
  actual_version="${actual_version#v}"
  if [ "$actual_version" != "$version" ]; then
    err "installed version ${actual_version} does not match FLOW_VERSION ${version}"
  fi
fi

# Verify the installed binary actually runs before declaring success.
info "Verifying with flow --version"
if PATH="${bin_dir}:$PATH" "$BIN_NAME" --version >/dev/null 2>&1; then
  success "Installation verified"
else
  err "installed binary failed to run: ${dest}"
fi

success "Installation complete"

printf '\n'
printf '\n'
printf 'Get started:\n'
printf "   %s login\n" "$BIN_NAME"
printf "   %s agents create\n" "$BIN_NAME"
printf "   %s runs start --agent <id> --follow\n" "$BIN_NAME"
printf '\n'
printf "Run %s --help for help.\n" "$BIN_NAME"

case ":$PATH:" in
  *":$bin_dir:"*) ;;
  *) printf "\n%s is not in your PATH; add it to use %s directly.\n" "$bin_dir" "$BIN_NAME" ;;
esac
