#!/usr/bin/env bash
set -euo pipefail

ROOT="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/.." && pwd)"

usage() {
  cat <<'EOF'
usage: rig <command> [args]

commands:
  bootstrap <control-plane|workload|runner|dev|workstation|custom>
            [--hostname <name>] [--class <human|server>] [--host <yes|no>]
            [--join <authkey|login>]
      OS plumbing on a pristine Debian box: hardening, unattended-upgrades,
      tailscale join. Roles are presets over the three traits; any flag
      overrides its trait, and custom states all of them. Prompts for a
      single-use TAGGED tailnet pre-auth key (TS_AUTHKEY env overrides the
      prompt); the key's tags are the tailnet tag, verified after join —
      only control-plane and workload may carry tag:server. join=login
      (workstation) needs no key: interactive login, node must come up
      untagged. Run as root.
  bootstrap <claude|codex|grok|staging> [--user <name>]
      The box TENANT roles: converge a box-minted guest. claude|codex|grok
      land the agent toolbelt (git, gh, tmux, docker), the agent's CLI on
      the system PATH, and the agent-context file (with the box#80 guard:
      never run box setup-host inside a box). staging lands box#69's server
      posture — docker + sshd hardening; its tailnet join stays operator-run
      via 'rig bootstrap workload'. Creds-free and non-interactive: box
      auto-runs these at mint. Run as root, inside the box.
  coolify install --version <pin>
      Pinned Coolify install (AUTOUPDATE=false). Control-plane box only.
  coolify backup install [options]
      Nightly age-encrypted dump of the control-plane database, as a
      systemd timer. rig installs the machinery and templates an empty
      0600 bindings file; you fill in the age recipient and S3 details.
      Control-plane box only. Run as root.
  db <dump|restore> ...
      Ad-hoc PostgreSQL dump/restore for a container on this box. `dump`
      writes a gzipped SQL artifact (--no-owner --no-acl, so it restores
      onto a different instance); `restore` loads one back, connecting as
      the container's own superuser, behind a confirm gate. Run as root.
  runner install --repo <owner/repo> [options]
      GitHub Actions runner as a systemd service under an unprivileged
      user — outbound-only, no Docker. Prompts for the short-lived
      registration token (RUNNER_TOKEN env overrides). Run as root.
  runner status [--user <name>]
      What this box's runner is registered to: repo, name, labels, unit.
      Reads the box only — no token, no network call. Run as root.
  runner remove [--local] [--user <name>]
      Take the service down and deregister the runner. Prompts for the
      short-lived removal token (RUNNER_REMOVE_TOKEN env overrides).
      Run as root.
  runner repoint --repo <owner/repo> [options]
      Move an installed runner to another repository — deregister, then
      re-register, reusing the binary already on the box. Needs a removal
      token for the old repo and a registration token for the new one.
      Run as root.
  users apply --file <path>
      Converge named operator accounts from a declarative users file, on
      every class: groups by role (admin/rig/box), passwords locked always,
      authorized_keys made exact, visudo-gated sudoers rules. Users dropped
      from the file are locked, never deleted. '-' reads stdin. Run as root.
  users status
      Roles (derived from actual group membership), key counts and lock
      state for the rig-managed users. Reads the box only. Run as root.
  users close-root
      Shut root SSH on a class=human box once an admin key works. Refuses
      on class=server — root there is the control plane's automation door —
      and while no admin holds a key. Run as root.

install/upgrade:
  curl -fsSL https://raw.githubusercontent.com/heavy-duty/rig/main/install.sh | bash
EOF
}

cmd="${1:-}"
case "$cmd" in
  bootstrap)
    shift
    exec "$ROOT/commands/bootstrap.sh" "$@"
    ;;
  coolify)
    shift
    sub="${1:-}"
    case "$sub" in
      install)
        shift
        exec "$ROOT/commands/coolify-install.sh" "$@"
        ;;
      backup)
        shift
        if [ "${1:-}" != "install" ]; then
          usage >&2
          exit 2
        fi
        shift
        exec "$ROOT/commands/coolify-backup-install.sh" "$@"
        ;;
      *)
        usage >&2
        exit 2
        ;;
    esac
    ;;
  db)
    shift
    case "${1:-}" in
      dump|restore|-h|--help)
        exec "$ROOT/commands/db.sh" "$@"
        ;;
      *)
        usage >&2
        exit 2
        ;;
    esac
    ;;
  runner)
    shift
    sub="${1:-}"
    case "$sub" in
      install)
        shift
        exec "$ROOT/commands/runner-install.sh" "$@"
        ;;
      status)
        shift
        exec "$ROOT/commands/runner-status.sh" "$@"
        ;;
      remove)
        shift
        exec "$ROOT/commands/runner-remove.sh" "$@"
        ;;
      repoint)
        shift
        exec "$ROOT/commands/runner-repoint.sh" "$@"
        ;;
      *)
        usage >&2
        exit 2
        ;;
    esac
    ;;
  users)
    shift
    sub="${1:-}"
    case "$sub" in
      apply)
        shift
        exec "$ROOT/commands/users-apply.sh" "$@"
        ;;
      status)
        shift
        exec "$ROOT/commands/users-status.sh" "$@"
        ;;
      close-root)
        shift
        exec "$ROOT/commands/users-close-root.sh" "$@"
        ;;
      *)
        usage >&2
        exit 2
        ;;
    esac
    ;;
  -h|--help|help)
    usage
    exit 0
    ;;
  "")
    usage >&2
    exit 2
    ;;
  *)
    printf 'rig: unknown command: %s\n' "$cmd" >&2
    usage >&2
    exit 2
    ;;
esac
