#!/usr/bin/env bash
#
# install.sh — install Hammy Devy for the current user (macOS and Linux).
#
#   curl -fsSL https://install.magic-rush.com/install.sh | bash
#
# Needs Node.js 22.19+ and nothing else: the native sandbox binaries come from
# npm as prebuilt platform packages, so there is no compiler step.
#
# Everything it writes lives under the Harness home ($DSH_HOME, default ~/.dsh)
# and the install directory ($HAMMY_DIR, default ~/.hammy-devy). Nothing is
# installed system-wide and no sudo is used.

set -euo pipefail

TARBALL_URL="${HAMMY_TARBALL_URL:-https://install.magic-rush.com/hammy-devy.tar.gz}"
GATEWAY_URL="${HAMMY_GATEWAY_URL:-https://gateway.magic-rush.com/v1}"
INSTALL_DIR="${HAMMY_DIR:-$HOME/.hammy-devy}"
DSH_HOME="${DSH_HOME:-$HOME/.dsh}"
PROFILE="hammy"
PNPM_VERSION="11.7.0"

say() { printf '%s\n' "$*"; }
die() { printf '\nerror: %s\n' "$*" >&2; exit 1; }

say ""
say "  Hammy Devy installer"
say "  ===================="
say ""

# ---------------------------------------------------------------- Node.js
command -v node >/dev/null 2>&1 \
  || die "Node.js is required. Install the LTS build from https://nodejs.org, open a new terminal, and run this again."

NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]')"
NODE_MINOR="$(node -p 'process.versions.node.split(".")[1]')"
if [ "$NODE_MAJOR" -lt 22 ] || { [ "$NODE_MAJOR" -eq 22 ] && [ "$NODE_MINOR" -lt 19 ]; }; then
  die "Node.js 22.19 or newer is required; this machine has $(node --version)."
fi
say "  Node.js $(node --version)  ok"

# ------------------------------------------------------------------- pnpm
if command -v pnpm >/dev/null 2>&1; then
  say "  pnpm $(pnpm --version)  ok"
else
  say "  enabling pnpm via corepack…"
  command -v corepack >/dev/null 2>&1 \
    || die "corepack is missing (it ships with Node.js). Install pnpm manually: npm install -g pnpm"
  corepack enable >/dev/null 2>&1 || true
  corepack prepare "pnpm@$PNPM_VERSION" --activate >/dev/null 2>&1 \
    || die "corepack could not activate pnpm@$PNPM_VERSION"
  say "  pnpm $PNPM_VERSION  ok"
fi

# ------------------------------------------------------------------- fetch
say ""
say "  Downloading Hammy Devy…"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
if ! curl -fsSL "$TARBALL_URL" -o "$TMP/hammy-devy.tar.gz"; then
  die "could not download $TARBALL_URL — check your connection, or ask support for the current link."
fi

mkdir -p "$INSTALL_DIR"
say "  Unpacking into $INSTALL_DIR"
tar -xzf "$TMP/hammy-devy.tar.gz" -C "$INSTALL_DIR"

APP_DIR="$INSTALL_DIR/hammy-devy"
[ -f "$APP_DIR/package.json" ] || die "the download did not contain the app; the file at $TARBALL_URL may be wrong."

# ------------------------------------------------------------------ the key
say ""
if [ -n "${HAMMY_KEY:-}" ]; then
  KEY="$HAMMY_KEY"
  say "  Using the key from HAMMY_KEY."
else
  say "  Paste the key from your welcome email, then press Enter."
  say "  (It starts with sk- and only works with Hammy Devy.)"
  say ""
  printf '  Key: '
  read -r KEY
fi
KEY="$(printf '%s' "$KEY" | tr -d '[:space:]')"
case "$KEY" in
  sk-*) ;;
  *) die "that does not look like a Hammy Devy key — it should start with sk-. Nothing was changed." ;;
esac

# --------------------------------------------------------------- the config
say ""
say "  Writing your profile…"
PROFILE_DIR="$DSH_HOME/profiles/$PROFILE"
mkdir -p "$PROFILE_DIR"
chmod 700 "$DSH_HOME" 2>/dev/null || true

# The bundle list mirrors a standard Hammy Devy profile: core, the web surface,
# and the Hammy layer.
cat > "$PROFILE_DIR/package.json" <<JSON
{
  "name": "dsh-profile-$PROFILE",
  "private": true,
  "dsh": {
    "profile": {
      "bundles": [
        "@deepseek-ai/dsh-base",
        "@deepseek-ai/dsh-web-app",
        "@deepseek-ai/dsh-hammy-bundle"
      ]
    }
  }
}
JSON

# Every request goes to our gateway, which holds the model key and meters your
# usage. The key written here is YOURS: it is scoped to this account, capped at
# your plan, and useless anywhere else.
cat > "$PROFILE_DIR/cordis.patch.yml" <<YAML
# Written by the Hammy Devy installer. Edits here are safe to keep, but
# re-running the installer replaces this file.
- id: llm-pi-ai
  name: "@deepseek-ai/dsh-llm-pi-ai"
  config:
    providers:
      hammy:
        displayName: Hammy Devy
        baseURL: $GATEWAY_URL
        api: openai-completions
        headers:
          Authorization: Bearer $KEY
        models:
          - id: deepseek-v4-pro
            name: DeepSeek-V4-Pro
          - id: deepseek-flash
            name: DeepSeek-V4.1-Flash
- id: agent-default-model
  name: "@deepseek-ai/dsh-agent-default-model"
  config:
    provider: hammy
    model: deepseek-flash
YAML
chmod 600 "$PROFILE_DIR/cordis.patch.yml"

# ------------------------------------------------------------------ launcher
cat > "$INSTALL_DIR/hammy-devy" <<LAUNCH
#!/usr/bin/env bash
cd "$APP_DIR" && exec pnpm dsh --profile $PROFILE "\$@"
LAUNCH
chmod +x "$INSTALL_DIR/hammy-devy"

# ------------------------------------------------------------------ install
say ""
say "  Installing dependencies (a minute or two)…"
# Dependencies only — deliberately no build. The tarball already carries the
# compiled artifacts, and its TypeScript output is platform-independent.
# Rebuilding here would fail: the build stamps the source commit with
# `git rev-parse HEAD`, and the tarball ships no `.git`.
#
# The native sandbox binaries arrive from npm as prebuilt platform packages, so
# this step needs no compiler.
cd "$APP_DIR"
pnpm install --frozen-lockfile >/dev/null 2>&1 \
  || die "dependency installation failed. Run this for the full output:  cd $APP_DIR && pnpm install --frozen-lockfile"

# ------------------------------------------------------------------- done
say ""
say "  Done."
say ""
say "  Start it with:"
say ""
say "      $INSTALL_DIR/hammy-devy"
say ""
say "  Your browser opens at http://127.0.0.1:3080 — pick the folder you want"
say "  the agent to work in, and start typing."
say ""
say "  Your install:  $APP_DIR"
say "  Your profile:  $PROFILE_DIR"
say "  Support:       https://whop.com/hammy-harness-cli-multi-ai-coding-agent/"
say ""
