#!/bin/sh
# ===========================================================================
#  AkiQai / ProximAgent node installer
#  Fetched from get.proximagent.com (full) or get.akiqai.com (node).
#  AKI is a non-monetary agent-interaction credit: zero fiat, by design.
#  Your node holds its own keys. Nothing here takes custody.
# ===========================================================================
set -e

PROFILE="node"
VERSION_STR="0.1.0-devnet"
DISTRIBUTION_RID_DEFAULT="rad:z26bGNWhPLbWyUu3ngFTWB886CbWE"
RAD_RID_DEFAULT=""
RAD_SEED_DEFAULT="https://seed.radicle.garden"
REPO_DEFAULT="https://github.com/ProximAgent/ProximAgent.git"
REF_DEFAULT="main"
COMMIT_DEFAULT=""
PROOF_CID_DEFAULT="bafybeic3j4zav3uadark5mdsr2nciqk2ui3cfd542avpmz4fxxx5mezmey"
MANIFEST_COMMIT_DEFAULT="be8edd7f7cf30abf0cafd9eda9b09e44503b8ed1"
MANIFEST_SHA256_DEFAULT="70b0cae230b5ef7a077750a5a979e61f8ed41a18eef3f3495c6a973c2cdd57eb"
MANIFEST_CID_DEFAULT="bafkreidqwdfoemfv555ao52quwuxtzq7r3kbugho6pzusxdks46czxkx5m"
MANIFEST_EXPIRES_DEFAULT="2026-10-22T00:00:00Z"

c_info() { echo "[akiqai] $1"; }
c_warn() { echo "[akiqai] WARN: $1" 1>&2; }
c_err()  { echo "[akiqai] ERROR: $1" 1>&2; }

banner() {
  echo "=============================================================="
  echo "  AkiQai node installer  -  join the live agent network"
  echo "  AKI is a non-monetary credit: zero fiat. Your keys stay yours."
  echo "=============================================================="
}

show_help() {
  echo "AkiQai / ProximAgent node installer ($VERSION_STR)"
  echo ""
  echo "Usage:  curl -fsSL https://get.proximagent.com | sh"
  echo "        curl -fsSL https://get.akiqai.com | sh"
  echo "        curl -fsSL https://get.akiqai.com | sh -s -- [options]"
  echo ""
  echo "Profiles (default set by the host you fetched from):"
  echo "  full   agent identity+wallet+inbox, free LLM (llm.proximagent.com),"
  echo "         AND a chain node (pin + witness on; validator gated)"
  echo "  node   an AkiQai chain node first (pin + witness/observer;"
  echo "         validator gated); the agent + LLM are opt-in"
  echo ""
  echo "Options:"
  echo "  --profile full|node   override the default profile"
  echo "  --pin / --no-pin      contribute durable proof storage (AQ-30)"
  echo "  --witness/--no-witness verify L1 checkpoints (observer.akiqai.com)"
  echo "  --agent               also run the ProximAgent agent + its free LLM"
  echo "  --llm / --no-llm      wire the ProximAgent LLM gateway"
  echo "  --llm-key <key>       bring-your-own LLM key instead of the free gateway"
  echo "  --flavor <name>       agent flavor (akiqai|openclaw|hermes|pi|claude|opencode|codex|copilot|atomic|custom)"
  echo "  --dir <path>          install dir (default: \$HOME/.akiqai-node)"
  echo "  --ui-port <n>         local dashboard port (default 4177)"
  echo "  --lan                 expose the dashboard on the LAN + advertise proximagent.local"
  echo "  --relay <https-url>   add an explicit AQ-32 relay (repeatable; never auto-trusts hosts)"
  echo "  --relay-manifest <url> use a signed AQ-32 relay manifest"
  echo "  --relay-root-key <hex> trust a relay-manifest ML-DSA root key (repeatable)"
  echo "  --direct-peer         opt in to authenticated direct AQ-32 LAN delivery"
  echo "  --direct-peer-port N  direct-peer port (default 4181)"
  echo "  --dry-run             print the plan and exit (installs nothing)"
  echo "  --no-run              set up but do not launch"
  echo "  --yes                 auto-install a missing runtime (Docker) and a sandbox backend"
  echo "  --version             print version and exit"
  echo "  -h, --help            this help"
}

# ---- defaults (per profile) ----------------------------------------------
DRY_RUN=0
ASSUME_YES=0
DO_RUN=1
LAN=0
TARGET="$HOME/.akiqai-node"
FLAVOR="akiqai"
LLM_KEY=""
UI_PORT=4177
RELAY_URLS="${PROXIMAGENT_RELAYS:-}"
RELAY_MANIFEST_URL="${PROXIMAGENT_RELAY_MANIFEST_URL:-}"
RELAY_ROOT_KEYS="${PROXIMAGENT_RELAY_ROOT_KEYS:-}"
DIRECT_PEER=0
DIRECT_PEER_PORT="${AQ32_DIRECT_PEER_PORT:-4181}"
case "$PROFILE" in
  full) PIN=1; WITNESS=1; LLM=1 ;;
  node) PIN=1; WITNESS=1; LLM=0 ;;
  *)    PIN=1; WITNESS=1; LLM=0; PROFILE=node ;;
esac

# ---- args ----------------------------------------------------------------
while [ $# -gt 0 ]; do
  case "$1" in
    --profile)
      PROFILE="$2"; shift 2
      case "$PROFILE" in
        full) LLM=1 ;;
        node) LLM=0 ;;
        *) c_err "unknown profile: $PROFILE (full|node)"; exit 2 ;;
      esac ;;
    --dry-run) DRY_RUN=1; shift ;;
    --yes|-y) ASSUME_YES=1; shift ;;
    --no-run) DO_RUN=0; shift ;;
    --dir) TARGET="$2"; shift 2 ;;
    --pin) PIN=1; shift ;;
    --no-pin) PIN=0; shift ;;
    --witness) WITNESS=1; shift ;;
    --no-witness) WITNESS=0; shift ;;
    --agent) LLM=1; shift ;;
    --llm) LLM=1; shift ;;
    --no-llm) LLM=0; shift ;;
    --llm-key) LLM=1; LLM_KEY="$2"; shift 2 ;;
    --flavor) FLAVOR="$2"; shift 2 ;;
    --ui-port) UI_PORT="$2"; shift 2 ;;
    --relay) RELAY_URLS="$RELAY_URLS${RELAY_URLS:+,}$2"; shift 2 ;;
    --relay-manifest) RELAY_MANIFEST_URL="$2"; shift 2 ;;
    --relay-root-key) RELAY_ROOT_KEYS="$RELAY_ROOT_KEYS${RELAY_ROOT_KEYS:+,}$2"; shift 2 ;;
    --direct-peer) DIRECT_PEER=1; shift ;;
    --direct-peer-port) DIRECT_PEER=1; DIRECT_PEER_PORT="$2"; shift 2 ;;
    --lan) LAN=1; shift ;;
    -h|--help) show_help; exit 0 ;;
    --version) echo "$VERSION_STR"; exit 0 ;;
    *) c_err "unknown option: $1 (try --help)"; exit 2 ;;
  esac
done

# ---- env overrides (documented) ------------------------------------------
RAD_RID="$RAD_RID_DEFAULT";   if [ -n "$PROXIMAGENT_RELEASE_RID" ]; then RAD_RID="$PROXIMAGENT_RELEASE_RID"; elif [ -n "$AKIQAI_RAD_RID" ]; then RAD_RID="$AKIQAI_RAD_RID"; fi
RAD_SEED="$RAD_SEED_DEFAULT"; if [ -n "$AKIQAI_RAD_SEED" ]; then RAD_SEED="$AKIQAI_RAD_SEED"; fi
REPO="$REPO_DEFAULT"; if [ -n "$AKIQAI_REPO" ]; then REPO="$AKIQAI_REPO"; fi
REF="$REF_DEFAULT";   if [ -n "$AKIQAI_REF" ]; then REF="$AKIQAI_REF"; fi

# ---- release manifest (baked at deploy time from the signed manifest) ----
MANIFEST_VALID=0
if [ -n "$MANIFEST_COMMIT_DEFAULT" ] || [ -n "$MANIFEST_CID_DEFAULT" ]; then
  if [ -n "$MANIFEST_EXPIRES_DEFAULT" ]; then
    NOW_UTC="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
    if awk -v a="$NOW_UTC" -v b="$MANIFEST_EXPIRES_DEFAULT" 'BEGIN { exit !(a < b) }'; then
      MANIFEST_VALID=1
    else
      c_warn "release manifest expired at $MANIFEST_EXPIRES_DEFAULT; ignoring manifest-sourced pin"
    fi
  else
    c_warn "release manifest has no expiry configured; ignoring manifest-sourced pin"
  fi
fi

EXPECTED_COMMIT="$COMMIT_DEFAULT"
if [ "$MANIFEST_VALID" = 1 ] && [ -n "$MANIFEST_COMMIT_DEFAULT" ]; then EXPECTED_COMMIT="$MANIFEST_COMMIT_DEFAULT"; fi
if [ -n "$AKIQAI_COMMIT" ]; then EXPECTED_COMMIT="$AKIQAI_COMMIT"; fi
if [ -n "$EXPECTED_COMMIT" ]; then
  case "$EXPECTED_COMMIT" in *[!0-9a-fA-F]*|'') c_err "the pinned commit (AKIQAI_COMMIT or manifest) must be a hexadecimal git object id"; exit 2 ;; esac
  COMMIT_LEN="$(printf %s "$EXPECTED_COMMIT" | wc -c | tr -d ' ')"
  if [ "$COMMIT_LEN" -ne 40 ] && [ "$COMMIT_LEN" -ne 64 ]; then c_err "the pinned commit (AKIQAI_COMMIT or manifest) must be 40 or 64 hex characters"; exit 2; fi
fi

# ---- OS / arch detection -------------------------------------------------
OS_RAW="$(uname -s)"
case "$OS_RAW" in
  Linux) OS=linux ;;
  Darwin) OS=macos ;;
  *) OS=unknown ;;
esac
ARCH_RAW="$(uname -m)"
case "$ARCH_RAW" in
  x86_64|amd64) ARCH=amd64 ;;
  aarch64|arm64) ARCH=arm64 ;;
  *) ARCH="$ARCH_RAW" ;;
esac

# ---- hang-guarded container runtime probes -------------------------------
# 'docker info' / 'podman info' can BLOCK FOREVER when their daemon is wedged
# (a stuck Docker Desktop is the canonical case; --dry-run used to hang here).
# Cap every probe at PROBE_TIMEOUT seconds: run it in the background, poll the
# pid with 'kill -0', kill it on timeout, and treat a timeout as "unavailable".
# Each runtime is probed at most once (cached), so a whole run never waits more
# than one timeout per engine. Portable POSIX sh: no timeout(1) dependency and
# no dollar-brace expansions (this script lives inside a JS template literal).
PROBE_TIMEOUT=8
probe_with_timeout() {
  "$@" >/dev/null 2>&1 &
  probe_pid=$!
  probe_waited=0
  while [ "$probe_waited" -lt "$PROBE_TIMEOUT" ]; do
    if ! kill -0 "$probe_pid" 2>/dev/null; then
      wait "$probe_pid"
      return $?
    fi
    sleep 1
    probe_waited=$(( probe_waited + 1 ))
  done
  kill "$probe_pid" 2>/dev/null || true
  wait "$probe_pid" 2>/dev/null || true
  c_warn "$1 info did not answer within $PROBE_TIMEOUT s; treating $1 as unavailable (is its daemon wedged?)"
  return 124
}

DOCKER_READY=""
docker_ready() {
  if [ -z "$DOCKER_READY" ]; then
    if command -v docker >/dev/null 2>&1 && probe_with_timeout docker info; then DOCKER_READY=yes; else DOCKER_READY=no; fi
  fi
  [ "$DOCKER_READY" = yes ]
}
PODMAN_READY=""
podman_ready() {
  if [ -z "$PODMAN_READY" ]; then
    if command -v podman >/dev/null 2>&1 && probe_with_timeout podman info; then PODMAN_READY=yes; else PODMAN_READY=no; fi
  fi
  [ "$PODMAN_READY" = yes ]
}

# ---- sandbox backend detection (nono -> OpenShell -> docker/podman) ------
detect_backend() {
  if command -v nono >/dev/null 2>&1; then echo nono; return 0; fi
  if command -v openshell >/dev/null 2>&1; then echo openshell; return 0; fi
  if docker_ready; then echo docker; return 0; fi
  if podman_ready; then echo podman; return 0; fi
  echo ""
}

# Soft-install is OPT-IN only (--yes), never as root, never destructive.
soft_install_backend() {
  if [ "$ASSUME_YES" != 1 ]; then return 1; fi
  if [ "$OS" = macos ] && command -v brew >/dev/null 2>&1; then
    c_info "attempting: brew install nono"
    if brew install nono; then return 0; fi
  fi
  return 1
}

# ---- runtime assurance: a container runtime (preferred) or Node >=20 ------
have_container() {
  docker_ready || podman_ready
}
node_major() {
  command -v node >/dev/null 2>&1 || return 1
  NODE_V=$(node -v 2>/dev/null | sed -e 's/^v//' -e 's/[.].*//')
  [ -n "$NODE_V" ] || return 1
  [ "$NODE_V" -ge 20 ] 2>/dev/null
}
have_runtime() { have_container || node_major; }
can_sudo() {
  [ "$(id -u)" = 0 ] && return 0
  command -v sudo >/dev/null 2>&1 || return 1
  sudo -n true >/dev/null 2>&1
}

# Always print the exact plan first; never pipe anything as root silently.
print_runtime_plan() {
  echo "" 1>&2
  c_warn "No container runtime and no Node >=20 found - a runtime is required."
  echo "  Pick ONE (Docker is recommended - the bare-Pi / bare-metal baseline):" 1>&2
  echo "" 1>&2
  echo "  A) Docker:" 1>&2
  echo "       curl -fsSL https://get.docker.com | sh" 1>&2
  if [ "$OS" = linux ]; then
    echo "     then enable ROOTLESS Docker (no daemon root):" 1>&2
    echo "       dockerd-rootless-setuptool.sh install" 1>&2
    echo "       systemctl --user enable --now docker" 1>&2
  fi
  echo "" 1>&2
  echo "  B) Node >=20 (for the nono / OpenShell source path):" 1>&2
  if [ "$OS" = macos ]; then
    echo "       brew install node" 1>&2
  else
    echo "       curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs" 1>&2
  fi
  echo "" 1>&2
  echo "  Then re-run this installer, or pass --yes to auto-install Docker now." 1>&2
}

# Auto-install a runtime (Docker preferred). OPT-IN via --yes; shows the plan
# first; never silent-root. Returns 0 only if a container runtime is now usable.
auto_install_runtime() {
  [ "$ASSUME_YES" = 1 ] || return 1
  c_info "no runtime found and --yes given -> installing Docker (the container baseline)."
  c_info "plan:  curl -fsSL https://get.docker.com | sh   (then rootless setup on Linux)"
  if [ "$OS" = macos ]; then
    if command -v brew >/dev/null 2>&1; then
      c_info "attempting: brew install --cask docker (you must then start Docker Desktop)"
      brew install --cask docker || true
    else
      c_warn "install Docker Desktop: https://www.docker.com/products/docker-desktop/"
    fi
    have_container && return 0
    return 1
  fi
  if can_sudo; then
    c_info "installing Docker via the official convenience script ..."
    curl -fsSL https://get.docker.com | sh || { c_err "Docker install failed"; return 1; }
    if command -v dockerd-rootless-setuptool.sh >/dev/null 2>&1; then
      c_info "configuring rootless Docker for $(id -un) ..."
      dockerd-rootless-setuptool.sh install || c_warn "rootless setup incomplete - see the steps above"
      if [ -z "$XDG_RUNTIME_DIR" ]; then XDG_RUNTIME_DIR="/run/user/$(id -u)"; fi
      DOCKER_HOST="unix://$XDG_RUNTIME_DIR/docker.sock"; export DOCKER_HOST
    fi
    have_container && return 0
    return 1
  fi
  c_err "Docker install needs sudo, which is not available for $(id -un)."
  c_err "Run these as an administrator, then re-run this installer:"
  echo "    curl -fsSL https://get.docker.com | sh" 1>&2
  if [ "$OS" = linux ]; then
    echo "    dockerd-rootless-setuptool.sh install && systemctl --user enable --now docker" 1>&2
  fi
  return 1
}

guide_backend() {
  c_warn "No sandbox backend found (need nono, OpenShell, Docker, or Podman)."
  echo "  Install ONE of these, then re-run this installer:" 1>&2
  if [ "$OS" = macos ]; then
    echo "    - Docker Desktop:  https://www.docker.com/products/docker-desktop/" 1>&2
    echo "    - nono (kernel sandbox):  brew install nono" 1>&2
  else
    echo "    - Podman (rootless):  https://podman.io/docs/installation" 1>&2
    echo "    - Docker Engine:  https://docs.docker.com/engine/install/" 1>&2
    echo "    - gVisor (runsc) for the strongest isolation:  https://gvisor.dev/docs/user_guide/install/" 1>&2
  fi
}

print_manual_steps() {
  echo "  Fetch the runner manually, then launch it:" 1>&2
  echo "    1. rad clone $RAD_RID $TARGET   # Radicle (decentralized), or:" 1>&2
  echo "       git clone $REPO $TARGET" 1>&2
  echo "    2. cd $TARGET/self-host" 1>&2
  echo "    3. ./run-agent.sh --ui" 1>&2
}

# ---- run -----------------------------------------------------------------
banner

if [ "$(id -u)" = 0 ]; then
  c_err "refusing to run as root. Run as your normal user - the agent must NOT have root."
  exit 1
fi

c_info "profile=$PROFILE  os=$OS  arch=$ARCH"
if [ -n "$RELAY_URLS" ]; then c_info "AQ-32 relays explicitly configured: $RELAY_URLS"; fi

# ---- auto-everything: ensure a RUNTIME first (container preferred, else Node) --
if have_runtime; then
  if have_container; then c_info "runtime OK: container (docker/podman)"; else c_info "runtime OK: node $(node -v 2>/dev/null)"; fi
elif [ "$DRY_RUN" = 1 ]; then
  if [ "$ASSUME_YES" = 1 ]; then c_info "(dry-run) no runtime; would auto-install Docker (--yes)"; else c_info "(dry-run) no runtime; would print the install plan and stop"; fi
  print_runtime_plan
else
  print_runtime_plan
  if ! auto_install_runtime; then
    c_err "no runtime available; install ONE of the options above, then re-run."
    exit 1
  fi
fi

# ---- sandbox backend label (nono -> OpenShell -> docker/podman) ---------------
BACKEND="$(detect_backend)"
if [ -z "$BACKEND" ]; then
  if soft_install_backend; then BACKEND="$(detect_backend)"; fi
fi
if [ -z "$BACKEND" ]; then
  if have_container; then
    BACKEND="container"
  else
    guide_backend
    if [ "$DRY_RUN" = 1 ]; then
      c_info "(dry-run) would stop here until a sandbox backend is installed"
    else
      exit 1
    fi
  fi
fi

# ---- fetch the self-host runner (IPFS manifest, then Radicle, then git) --
RUNNER=""
if [ -d "$TARGET/self-host" ]; then
  c_info "reusing existing runner at $TARGET/self-host"
  RUNNER="$TARGET/self-host"
elif [ "$DRY_RUN" = 1 ]; then
  if [ "$MANIFEST_VALID" = 1 ] && [ -n "$MANIFEST_CID_DEFAULT" ]; then
    c_info "(dry-run) would fetch runner: IPFS $MANIFEST_CID_DEFAULT (manifest-pinned) first, then Radicle rad:$RAD_RID, then git $REPO (ref $REF)"
  else
    c_info "(dry-run) would fetch runner: Radicle rad:$RAD_RID first, then git $REPO (ref $REF)"
  fi
  RUNNER="$TARGET/self-host"
else
  fetched=0
  FETCH_METHOD=""
  # 0) IPFS — the signed release manifest's content-addressed archive, sha256-
  #    verified before extraction. Tried first when the manifest is unexpired.
  if [ "$fetched" = 0 ] && [ "$MANIFEST_VALID" = 1 ] && [ -n "$MANIFEST_CID_DEFAULT" ] && [ -n "$MANIFEST_SHA256_DEFAULT" ] && command -v ipfs >/dev/null 2>&1; then
    c_info "fetching runner from IPFS: $MANIFEST_CID_DEFAULT"
    mkdir -p "$TARGET"
    if ipfs get "$MANIFEST_CID_DEFAULT" -o "$TARGET/release.tar" >/dev/null 2>&1; then
      if command -v shasum >/dev/null 2>&1; then
        ACTUAL_SHA256="$(shasum -a 256 "$TARGET/release.tar" | awk '{print $1}')"
        if [ "$ACTUAL_SHA256" = "$MANIFEST_SHA256_DEFAULT" ]; then
          if tar -xf "$TARGET/release.tar" -C "$TARGET" >/dev/null 2>&1; then fetched=1; FETCH_METHOD=ipfs; fi
        else
          c_err "release archive hash mismatch (expected $MANIFEST_SHA256_DEFAULT, got $ACTUAL_SHA256); refusing to use it"
        fi
      else
        c_warn "shasum not found; cannot verify the release archive hash, skipping IPFS path"
      fi
    fi
  fi
  # 1) Radicle — decentralized, primary. rad clone if the CLI is present.
  if [ "$fetched" = 0 ] && [ -n "$RAD_RID" ] && command -v rad >/dev/null 2>&1; then
    c_info "fetching runner from Radicle: rad clone $RAD_RID"
    if rad clone "$RAD_RID" "$TARGET" >/dev/null 2>&1; then fetched=1; FETCH_METHOD=radicle; fi
  fi
  # 2) git fallback — a neutral remote (no personal account); only if configured.
  if [ "$fetched" = 0 ] && [ -n "$REPO" ] && command -v git >/dev/null 2>&1; then
    c_info "falling back to git clone $REPO (ref $REF)"
    if git clone --depth 1 --branch "$REF" "$REPO" "$TARGET" >/dev/null 2>&1; then fetched=1; FETCH_METHOD=git; fi
  fi
  if [ "$fetched" = 1 ]; then
    if [ "$FETCH_METHOD" = ipfs ]; then
      c_info "verified release archive sha256: $MANIFEST_SHA256_DEFAULT"
    elif [ -n "$EXPECTED_COMMIT" ]; then
      ACTUAL_COMMIT="$(git -C "$TARGET" rev-parse HEAD 2>/dev/null || true)"
      if [ "$ACTUAL_COMMIT" != "$EXPECTED_COMMIT" ]; then
        c_err "runner source verification failed (expected $EXPECTED_COMMIT, got $ACTUAL_COMMIT)"
        c_err "nothing will be launched; inspect or remove $TARGET before retrying"
        exit 1
      fi
      c_info "verified runner commit: $ACTUAL_COMMIT"
    else
      c_warn "runner commit is not pinned: unpinned installer is following ref $REF"
    fi
    RUNNER="$TARGET/self-host"
  else
    c_err "could not fetch the runner from IPFS, Radicle, or git."
    c_err "set PROXIMAGENT_RELEASE_RID (full runner RID) or AKIQAI_REPO (git remote), or install manually."
    print_manual_steps
    exit 1
  fi
fi

# ---- assemble run-agent.sh flags -----------------------------------------
LLM_STR=off; if [ "$LLM" = 1 ]; then LLM_STR=on; fi
FLAGS="--ui --ui-port $UI_PORT"
if [ "$WITNESS" = 1 ]; then FLAGS="$FLAGS --witness"; fi
if [ "$PIN" = 1 ]; then FLAGS="$FLAGS --pin"; fi
if [ "$LLM" = 1 ]; then FLAGS="$FLAGS --llm"; fi
if [ -n "$LLM_KEY" ]; then FLAGS="$FLAGS --llm-key $LLM_KEY"; fi
if [ "$FLAVOR" != akiqai ]; then FLAGS="$FLAGS --flavor $FLAVOR"; fi
if [ "$LAN" = 1 ]; then FLAGS="$FLAGS --lan"; fi
if [ "$ASSUME_YES" = 1 ]; then FLAGS="$FLAGS --install-runtime"; fi
if [ "$DIRECT_PEER" = 1 ]; then FLAGS="$FLAGS --direct-peer --direct-peer-port $DIRECT_PEER_PORT"; fi

# The pin role needs the canonical proof CID. Prefer an env override, else the
# value baked by the worker (may be empty -> the pin role prints guidance).
PIN_CID_VAL="$PROOF_CID_DEFAULT"
if [ -n "$PIN_CID" ]; then PIN_CID_VAL="$PIN_CID"; fi
export PIN_CID="$PIN_CID_VAL"

# ---- print the plan (always, before doing anything) ----------------------
echo ""
c_info "Plan:"
echo "    profile   : $PROFILE"
echo "    sandbox   : $BACKEND"
echo "    runner    : $RUNNER/run-agent.sh"
echo "    roles     : agent(always)  pin=$PIN  witness=$WITNESS  validator=GATED"
echo "    llm       : $LLM_STR"
echo "    command   : ./run-agent.sh $FLAGS"
echo ""

if [ "$DRY_RUN" = 1 ]; then
  c_info "dry-run complete - nothing was installed or started."
  exit 0
fi

if [ -z "$RUNNER" ] || [ ! -f "$RUNNER/run-agent.sh" ]; then
  c_err "runner not available at $RUNNER"
  print_manual_steps
  exit 1
fi

if [ "$DO_RUN" != 1 ]; then
  c_info "prepared. To start:  cd $RUNNER && ./run-agent.sh $FLAGS"
  exit 0
fi

c_info "launching:  ./run-agent.sh $FLAGS"
cd "$RUNNER"
if [ -n "$RELAY_URLS" ]; then export PROXIMAGENT_RELAYS="$RELAY_URLS"; fi
if [ -n "$RELAY_MANIFEST_URL" ]; then export PROXIMAGENT_RELAY_MANIFEST_URL="$RELAY_MANIFEST_URL"; fi
if [ -n "$RELAY_ROOT_KEYS" ]; then export PROXIMAGENT_RELAY_ROOT_KEYS="$RELAY_ROOT_KEYS"; fi
if command -v bash >/dev/null 2>&1; then
  exec bash ./run-agent.sh $FLAGS
fi
chmod +x ./run-agent.sh 2>/dev/null || true
exec ./run-agent.sh $FLAGS
