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

# Register an AWOOOI non-110 Gitea act_runner without putting the runner token
# in shell history, argv, logs, or command output. Run this from an interactive
# SSH TTY on the target host after the user-level runner installer has prepared
# config and systemd units. Codex must not run the token entry path.

GITEA_INSTANCE="${GITEA_INSTANCE:-http://192.168.0.110:3001}"
RUNNER_NAME="${RUNNER_NAME:-awoooi-non110-188}"
RUNNER_LABELS="${RUNNER_LABELS:-awoooi-non110-host:host,awoooi-non110-ubuntu:docker://192.168.0.110:5000/awoooi/ci-runner:act-22.04}"
RUNNER_DIR="${RUNNER_DIR:-${HOME}/act-runner-awoooi}"
RUNNER_BINARY="${RUNNER_BINARY:-${RUNNER_DIR}/act_runner}"
RUNNER_CONFIG="${RUNNER_CONFIG:-${RUNNER_DIR}/config.yaml}"
RUNNER_REGISTRATION="${RUNNER_REGISTRATION:-${RUNNER_DIR}/.runner}"

usage() {
  cat <<'EOF'
Usage:
  ops/runner/register-awoooi-non110-runner.sh --check
  ops/runner/register-awoooi-non110-runner.sh

Remote registration:
  Copy this script to the target host first, then run it from ssh -tt.
  Do not pipe the script over stdin for the real registration path, because
  token entry needs the interactive TTY.

Environment overrides:
  GITEA_INSTANCE, RUNNER_NAME, RUNNER_LABELS, RUNNER_DIR, RUNNER_BINARY,
  RUNNER_CONFIG, RUNNER_REGISTRATION

Safety contract:
  - requires an interactive TTY for token entry
  - reads the runner token with terminal echo disabled
  - refuses RUNNER_TOKEN from the environment
  - feeds the token to act_runner over stdin, not argv
  - never prints the token or .runner content
  - refuses to overwrite an existing non-empty registration unless
    ALLOW_REREGISTER=1 is set
EOF
}

log() {
  printf '%s\n' "$*"
}

die() {
  printf 'ERROR %s\n' "$*" >&2
  exit 1
}

metadata() {
  log "secret_values_collected_by_codex=false"
  log "runner_token_echoed=false"
  log "runner_token_in_argv=false"
  log "raw_runner_registration_read=false"
  log "gitea_instance=${GITEA_INSTANCE}"
  log "runner_name=${RUNNER_NAME}"
  log "runner_dir=${RUNNER_DIR}"
  log "runner_binary=${RUNNER_BINARY}"
  log "runner_config=${RUNNER_CONFIG}"
  log "runner_registration=${RUNNER_REGISTRATION}"
}

preflight() {
  [ -d "$RUNNER_DIR" ] || die "runner_dir_missing:${RUNNER_DIR}"
  [ -x "$RUNNER_BINARY" ] || die "runner_binary_missing_or_not_executable:${RUNNER_BINARY}"
  [ -r "$RUNNER_CONFIG" ] || die "runner_config_missing_or_not_readable:${RUNNER_CONFIG}"

  if [ -s "$RUNNER_REGISTRATION" ] && [ "${ALLOW_REREGISTER:-0}" != "1" ]; then
    log "runner_registration_present=1"
    log "safe_next_step=enable_service_and_rerun_non110_readiness_verifier"
    exit 0
  fi
}

require_tty() {
  if [ -t 0 ]; then
    return 0
  fi
  { : </dev/tty; } 2>/dev/null || die "interactive_tty_required"
}

read_token_from_tty() {
  local prompt="Gitea runner token: "
  set +x
  HISTFILE=/dev/null
  export HISTFILE
  if { : </dev/tty; } 2>/dev/null; then
    IFS= read -r -s -p "$prompt" RUNNER_TOKEN </dev/tty
    printf '\n' >/dev/tty
  else
    IFS= read -r -s -p "$prompt" RUNNER_TOKEN
    printf '\n'
  fi
  [ -n "${RUNNER_TOKEN:-}" ] || die "runner_token_empty"
}

register_runner() {
  cd "$RUNNER_DIR"
  set +x
  printf '%s\n' "$RUNNER_TOKEN" | "$RUNNER_BINARY" register \
    --instance "$GITEA_INSTANCE" \
    --name "$RUNNER_NAME" \
    --labels "$RUNNER_LABELS" \
    --config "$RUNNER_CONFIG"
  unset RUNNER_TOKEN
}

postcheck() {
  [ -s "$RUNNER_REGISTRATION" ] || die "runner_registration_not_created:${RUNNER_REGISTRATION}"
  chmod go-rwx "$RUNNER_REGISTRATION" 2>/dev/null || true
  log "runner_registration_present=1"
  log "runner_registration_content_read=false"
  log "safe_next_step=enable_service_and_rerun_non110_readiness_verifier"
}

main() {
  if [ "${1:-}" = "--help" ] || [ "${1:-}" = "-h" ]; then
    usage
    exit 0
  fi
  if [ "${1:-}" = "--check" ] || [ "${1:-}" = "--dry-run" ]; then
    DRY_RUN=1
    export DRY_RUN
    shift
  fi
  if [ "$#" -gt 0 ]; then
    usage >&2
    exit 2
  fi

  umask 077
  trap 'unset RUNNER_TOKEN 2>/dev/null || true' EXIT

  if [ "${RUNNER_TOKEN+x}" = "x" ]; then
    die "runner_token_env_not_allowed"
  fi

  metadata
  preflight

  if [ "${DRY_RUN:-0}" = "1" ]; then
    log "dry_run=true"
    log "safe_next_step=run_this_script_from_interactive_tty_without_capturing_token"
    exit 0
  fi

  require_tty
  read_token_from_tty
  register_runner
  postcheck
}

main "$@"
