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

# Register the AWOOOI 110 controlled CD drain lane without putting the runner
# token in shell history, argv, environment, logs, or command output. Codex must
# not run the token entry path; it is for an interactive TTY on 110.

GITEA_INSTANCE="${GITEA_INSTANCE:-http://192.168.0.110:3001}"
RUNNER_NAME="${RUNNER_NAME:-awoooi-110-cd-lane-drain}"
RUNNER_LABELS="${RUNNER_LABELS:-awoooi-host:host,awoooi-ubuntu:docker://192.168.0.110:5000/awoooi/ci-runner:act-22.04}"
RUNNER_DIR="${RUNNER_DIR:-/home/wooo/awoooi-cd-lane-drain}"
RUNNER_WORKDIR="${RUNNER_WORKDIR:-${RUNNER_DIR}/data}"
RUNNER_BINARY="${RUNNER_BINARY:-${RUNNER_DIR}/awoooi_cd_lane_controlled}"
RUNNER_CONFIG="${RUNNER_CONFIG:-${RUNNER_DIR}/config.yaml}"
RUNNER_REGISTRATION="${RUNNER_REGISTRATION:-${RUNNER_WORKDIR}/.runner}"
SERVICE_NAME="${SERVICE_NAME:-awoooi-cd-lane-drain.service}"
READINESS_VERIFIER="${READINESS_VERIFIER:-/usr/local/bin/check-awoooi-110-controlled-cd-lane-readiness.sh}"
DRY_RUN=0
ENABLE_SERVICE_AFTER_REGISTRATION=0

usage() {
  cat <<'EOF'
Usage:
  ops/runner/register-awoooi-110-controlled-cd-lane-drain.sh --check
  ops/runner/register-awoooi-110-controlled-cd-lane-drain.sh
  ops/runner/register-awoooi-110-controlled-cd-lane-drain.sh --enable-service

Remote registration:
  Copy this script to 110 first, then run it from ssh -tt on the target host.
  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_WORKDIR,
  RUNNER_BINARY, RUNNER_CONFIG, RUNNER_REGISTRATION, SERVICE_NAME,
  READINESS_VERIFIER

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
  - only starts the service when --enable-service is explicit and the
    non-secret readiness verifier passes with REQUIRE_ACTIVE_SERVICE=0
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_labels=${RUNNER_LABELS}"
  log "runner_dir=${RUNNER_DIR}"
  log "runner_workdir=${RUNNER_WORKDIR}"
  log "runner_binary=${RUNNER_BINARY}"
  log "runner_config=${RUNNER_CONFIG}"
  log "runner_registration=${RUNNER_REGISTRATION}"
  log "service_name=${SERVICE_NAME}"
  log "readiness_verifier=${READINESS_VERIFIER}"
  log "enable_service_after_registration=${ENABLE_SERVICE_AFTER_REGISTRATION}"
}

preflight() {
  [ -d "$RUNNER_DIR" ] || die "runner_dir_missing:${RUNNER_DIR}"
  [ -d "$RUNNER_WORKDIR" ] || die "runner_workdir_missing:${RUNNER_WORKDIR}"
  [ -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 "runner_registration_content_read=false"
    if [ "$ENABLE_SERVICE_AFTER_REGISTRATION" = "1" ]; then
      if [ "$DRY_RUN" = "1" ]; then
        log "dry_run=true"
        log "safe_next_step=enable_service_after_registration_with_verifier"
        exit 0
      fi
      enable_service
      exit $?
    fi
    log "safe_next_step=enable_awoooi_cd_lane_drain_service_and_rerun_110_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_WORKDIR"
  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_registration() {
  [ -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"
}

verifier_available() {
  [ -x "$READINESS_VERIFIER" ]
}

pre_enable_guard() {
  if ! verifier_available; then
    die "readiness_verifier_missing_or_not_executable:${READINESS_VERIFIER}"
  fi
  log "pre_enable_verifier_start=1"
  REQUIRE_ACTIVE_SERVICE=0 "$READINESS_VERIFIER"
}

enable_service() {
  pre_enable_guard
  log "service_enable_requested=1"
  sudo -n systemctl daemon-reload
  sudo -n systemctl enable --now "$SERVICE_NAME"
  log "service_enable_attempted=1"
  if verifier_available; then
    "$READINESS_VERIFIER"
  else
    log "safe_next_step=rerun_110_controlled_cd_lane_readiness_verifier"
  fi
}

main() {
  while [ "$#" -gt 0 ]; do
    case "$1" in
      --help|-h)
        usage
        exit 0
        ;;
      --check|--dry-run)
        DRY_RUN=1
        ;;
      --enable-service)
        ENABLE_SERVICE_AFTER_REGISTRATION=1
        ;;
      *)
        usage >&2
        exit 2
        ;;
    esac
    shift
  done

  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" = "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_registration

  if [ "$ENABLE_SERVICE_AFTER_REGISTRATION" = "1" ]; then
    enable_service
  else
    log "safe_next_step=enable_awoooi_cd_lane_drain_service_and_rerun_110_readiness_verifier"
  fi
}

main "$@"
