# vast-gpu-help: the usage blocks, sourced by the front door.
# They live apart because they are prose, and because help that lies costs more
# than no help: every flag listed here is one the wrapper actually parses.

# Exit codes are the executor's; these are the meanings this client reports.
explain() {
  case "$1" in
    0) echo "ok" ;;
    2) echo "error" ;;
    3) echo "not_submitted" ;;
    4) echo "duplicate" ;;
    5) echo "ambiguous" ;;
    6) echo "guardian_absent" ;;
    7) echo "not_ready" ;;
    8) echo "committed_mirror_failed" ;;
    10) echo "committed_execution_failed" ;;
    *) echo "unmapped_exit_$1" ;;
  esac
}

explain_verify() {
  case "$1" in
    0) echo "guest_reports_key_installed" ;;
    4) echo "key_absent_from_guest" ;;
    5) echo "key_file_unreadable_or_no_snapshot" ;;
    6) echo "nothing_reported_by_guest" ;;
    *) echo "unmapped_exit_$1" ;;
  esac
}

# Per-verb help. The wrapper's own flags differ from the executor's, so
# forwarding --help to the executor answered a different question and, until the
# binary named the flag, answered it with "unknown flag".
verb_usage() {
  case "$1" in
    offers) cat <<'U'
offers - read the live market, ranked. Nothing is reserved or spent.
  --gpu-name <s> --num-gpus <n> --min-gpu-ram <mb> --min-cpu-ram <mb>
  --min-cpu-cores <n> --min-disk <gb> --working-gb <gb> --min-reliability <0-1>
  --max-dph <usd> --min-inet-down-mbps <n> --min-disk-bw-mbps <n>
  --min-compute-cap <n> --min-cuda-max <n> --min-dlperf <n>
  --country <cc> --limit <n> --timeout-secs <n> --json --force
Volatility: offers are a point-in-time observation, not a reservation.
An identical query inside the cooldown is refused, quoting the previous verdict.
U
      ;;
    preflight) cat <<'U'
preflight <plan.json> [--json] - admit a plan against the live market.
Reads the plan, checks the selected offer still exists at the declared price,
and prints plan, selected offer, transfer cost and budget headroom.
Without a headroom_microusd in the plan the cost goes unreviewed, and says so.
U
      ;;
    up) cat <<'U'
up --ask <offer-id> --image <img> --onstart-file <file> --disk-gb <n>
   [--key <public-key-file>|--ssh-pubkey <file>] [--label <forgia-x-hex>]
   [--not-after <epoch-ms>]
Allocates, then attaches the SSH key and binds the identity to the instance, so
`where` never has to guess a key. It does not retry.
Env: VAST_NOT_AFTER (epoch ms), VAST_SSH_PUBKEY.
U
      ;;
    where) cat <<'U'
where <id> [--wait] - status, then the exact ssh line with the bound identity.
--wait polls inside this one call and prints state changes only. It is
read-only and free: no more shell loops around a status check.
U
      ;;
    ssh) cat <<'U'
ssh <id> [-- command...] - run over ssh with the identity bound to that
instance. Without a command it prints the ssh line and does not connect.
U
      ;;
    ssh-verify) cat <<'U'
ssh-verify <id> [--key <public-key-file>] [--deadline <secs>] - read-only and
free. Proves the guest has the key in authorized_keys. Exit 0 verified,
4 key absent, 5 unreadable/no snapshot, 6 the guest reported nothing.
A provider-accepted key is not a guest-installed key: never probe keys by ssh.
U
      ;;
    burn) cat <<'U'
burn <id> --yes - destroy, then prove absence. Exit 5 means the provider did
not confirm and the id is NOT recorded as destroyed; reconcile with inventory.
Never re-send an ambiguous destroy.
U
      ;;
    logs) cat <<'U'
logs <id> [--tail <n>] [--filter <s>] - the instance's own log.
U
      ;;
    exec) cat <<'U'
exec <forgia-executor args...> - any other subcommand, with the same token
extraction, evidence directory and run record. Use it instead of hand-rolling
mktemp plus awk to build a token file.
U
      ;;
    last) echo "last [n] - the recent calls, newest first, with verb, exit code and summary." ;;
    inventory|instance) cat <<'U'
inventory            every owned instance with USD/h and a BILLING line
instance <id> [--json]   one instance, full projection
Ownership is source of truth: a box running 5 hours is the shape to recognise.
U
      ;;
    *) echo "no per-verb help for '$1'; run 'vast-gpu help'." ;;
  esac
}

usage() {
  cat <<'USAGE'
vast-gpu: local Vast client (wraps executor/target/release/forgia-executor)

  inventory                          owned instances, state, USD/h, ssh
  instance <id>                      one read-only instance read
  offers <flags>                     ranked market read (--json for the receipt)
  preflight <plan.json> [--json]     admit a plan against the live market
  up --ask <id> --image <img> --onstart-file <file> --disk-gb <n>
  where <id> [--wait]                status, then the exact ssh command
  ssh <id> [-- command...]           run over ssh with the bound identity
  ssh-verify <id> [--key <pub>]      prove the key reached the guest, free
  logs <id> [--tail n] [--filter s]  the instance's own log
  gpu <id>                           per-GPU use, power, and what is running
  tail <id> --log <p> [--follow s]   that run's log, streamed to a verdict
  push <id> <dir> [--to <p>]         send a directory (local syntax check first)
  launch <id> --dir <d> --script <f> sync, start detached, prove it stayed alive
  runs <id>                          every run launched on this box
  burn <id> --yes                    destroy, then prove absence
  exec <executor-args...>            any other subcommand, same discipline
  last [n]                           recent calls with verb, exit, summary
  doctor                             check binary, token, evidence root, keys
  path [--check]                     resolved executor binary

Environment
  FORGIA_EXECUTOR, VAST_CRED_FILE, VAST_EVIDENCE_ROOT, VAST_SSH_PUBKEY,
  VAST_NOT_AFTER (epoch ms), VAST_COOLDOWN_SECS, VAST_RATE_COOLDOWN_SECS
  VAST_JSON=1 exports --json for offers and preflight.

Policy: no retries, no fallbacks, every call writes a fresh evidence directory.
Ambiguous destroy (exit 5) is never re-sent; reconcile with `inventory`.
`where --wait` and `ssh-verify` are read-only and free. Probing candidate keys
against a host is forbidden; attach one and verify it instead.
USAGE
}
