#!/bin/sh
# AutoSE installer (macOS / Linux)
# Clones AutoSE and sets up the `autose` CLI with uv.
#
#   curl -fsSL https://autose.dev/install.sh | sh
#
# Honors these environment variables:
#   AUTOSE_HOME     where to clone AutoSE        (default: $HOME/.autose-cli)
#   AUTOSE_BIN_DIR  where to place the launcher  (default: $HOME/.local/bin)
#   AUTOSE_REF      git ref to check out         (default: the repo default branch)

set -eu

REPO_URL="https://github.com/AutoSE-Labs/autose.git"
INSTALL_DIR="${AUTOSE_HOME:-$HOME/.autose-cli}"
BIN_DIR="${AUTOSE_BIN_DIR:-$HOME/.local/bin}"
REF="${AUTOSE_REF:-}"

# Pretty output
if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]; then
  BOLD=$(printf '\033[1m'); DIM=$(printf '\033[2m'); RESET=$(printf '\033[0m')
  INK=$(printf '\033[38;5;24m'); SIGNAL=$(printf '\033[38;5;166m')
else
  BOLD=""; DIM=""; RESET=""; INK=""; SIGNAL=""
fi
say()  { printf '%s\n' "$*"; }
step() { printf '%s>%s %s\n' "$SIGNAL" "$RESET" "$*"; }
die()  { printf '%serror:%s %s\n' "$SIGNAL" "$RESET" "$*" >&2; exit 1; }

say ""
say "${BOLD}${INK}AutoSE${RESET}  sovereign autonomous software engineering"
say "${DIM}local-first, org-aware, zero cloud${RESET}"
say ""

# Prerequisites
command -v git >/dev/null 2>&1 || die "git is required but was not found. Install it from https://git-scm.com"

# uv manages the Python runtime and dependencies. Install it if it is missing.
if ! command -v uv >/dev/null 2>&1; then
  step "Installing uv (Python toolchain manager)"
  curl -LsSf https://astral.sh/uv/install.sh | sh >/dev/null 2>&1 \
    || die "Could not install uv automatically. Install it from https://docs.astral.sh/uv/ and re-run."
  # uv drops its binary in one of these; make it available for the rest of this run.
  for d in "$HOME/.local/bin" "$HOME/.cargo/bin"; do
    [ -x "$d/uv" ] && PATH="$d:$PATH"
  done
  command -v uv >/dev/null 2>&1 \
    || die "uv was installed but is not on your PATH yet. Open a new terminal and re-run this installer."
fi

# Fetch
if [ -d "$INSTALL_DIR/.git" ]; then
  step "Updating AutoSE in $INSTALL_DIR"
  git -C "$INSTALL_DIR" fetch --depth 1 origin >/dev/null 2>&1
  if [ -n "$REF" ]; then
    git -C "$INSTALL_DIR" checkout -q "$REF"
    git -C "$INSTALL_DIR" reset --hard -q "origin/$REF" 2>/dev/null || git -C "$INSTALL_DIR" pull -q
  else
    git -C "$INSTALL_DIR" reset --hard -q '@{u}' 2>/dev/null || git -C "$INSTALL_DIR" pull -q
  fi
else
  [ -e "$INSTALL_DIR" ] && die "$INSTALL_DIR already exists but is not a git checkout. Remove it or set AUTOSE_HOME."
  step "Cloning AutoSE into $INSTALL_DIR"
  if [ -n "$REF" ]; then
    git clone --depth 1 --branch "$REF" "$REPO_URL" "$INSTALL_DIR" >/dev/null 2>&1 \
      || die "Failed to clone $REPO_URL at ref $REF"
  else
    git clone --depth 1 "$REPO_URL" "$INSTALL_DIR" >/dev/null 2>&1 \
      || die "Failed to clone $REPO_URL"
  fi
fi

# Set up the environment (uv fetches Python and installs dependencies)
step "Setting up the Python environment with uv (this can take a minute)"
( cd "$INSTALL_DIR" && uv sync >/dev/null 2>&1 ) \
  || die "uv sync failed. Run 'uv sync' in $INSTALL_DIR to see the error."

# Link the launcher
step "Linking the autose launcher into $BIN_DIR"
mkdir -p "$BIN_DIR"
LAUNCHER="$BIN_DIR/autose"
cat > "$LAUNCHER" <<EOF
#!/bin/sh
# AutoSE launcher, generated by install.sh
exec uv run --project "$INSTALL_DIR" autose "\$@"
EOF
chmod +x "$LAUNCHER"

# Done
say ""
say "${BOLD}AutoSE is installed.${RESET}"
say ""

case ":$PATH:" in
  *":$BIN_DIR:"*) ;;
  *)
    say "${SIGNAL}One more step.${RESET} $BIN_DIR is not on your PATH yet."
    say "Add this line to your shell profile (~/.zshrc, ~/.bashrc, and so on):"
    say ""
    say "    ${BOLD}export PATH=\"$BIN_DIR:\$PATH\"${RESET}"
    say ""
    ;;
esac

say "Next steps:"
say "  1. Point AutoSE at your model. It works with any OpenAI-compatible endpoint"
say "     (Ollama, LM Studio, vLLM, and so on). Set base_url and model in"
say "     ${DIM}~/.config/autose/config.yaml${RESET}, or copy ${DIM}profiles/config.yaml${RESET} from the repo."
say "  2. Run ${BOLD}autose${RESET} in your project to start an interactive session."
say ""
