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

# Два шага (рекомендуется — пароль не светится в install-команде):
#   1) TOKEN=$(bash install-ringo-linux.sh get-token --ringo URL --user admin)
#      # пароль и TOTP спросятся интерактивно
#   2) sudo bash install-ringo-linux.sh --ringo URL --token "$TOKEN"
#
# Одной командой (менее безопасно — пароль в argv/history):
#   sudo bash install-ringo-linux.sh --ringo URL --user USER --pass PASS [--totp CODE]

usage() {
  cat <<EOF
Usage:
  $0 get-token --ringo URL --user USER [--pass PASS] [--totp CODE]
  $0 --ringo URL --token TOKEN
  $0 --ringo URL --user USER --pass PASS [--totp CODE]

Env fallback: RINGO, RINGO_USER, RINGO_PASS, RINGO_TOTP, RINGO_TOKEN
EOF
}

enroll_auth() {
  local ringo="$1" user="$2" pass="$3" totp="$4"
  local body
  command -v jq >/dev/null 2>&1 || { echo "jq is required for --user/--pass auth (or pass --token instead)" >&2; exit 1; }
  if [ -n "$totp" ]; then
    body=$(jq -n --arg u "$user" --arg p "$pass" --arg t "$totp" \
      '{username:$u,password:$p,two_factor_auth_code:$t}')
  else
    body=$(jq -n --arg u "$user" --arg p "$pass" \
      '{username:$u,password:$p}')
  fi
  curl -fsS -X POST "$ringo/enroll/auth" \
    -H 'Content-Type: application/json' \
    -d "$body" \
    | jq -r '.access_token'
}

parse_common_args() {
  RINGO="${RINGO:-https://mdm.company.ru}"
  AUTH_USER="${RINGO_USER:-}"
  PASS="${RINGO_PASS:-}"
  TOTP="${RINGO_TOTP:-}"
  TOKEN="${RINGO_TOKEN:-}"

  while [ $# -gt 0 ]; do
    case "$1" in
      --ringo)
        RINGO="${2:?--ringo needs a value}"; shift 2 ;;
      --user)
        AUTH_USER="${2:?--user needs a value}"; shift 2 ;;
      --pass)
        PASS="${2:?--pass needs a value}"; shift 2 ;;
      --totp)
        TOTP="${2:?--totp needs a value}"; shift 2 ;;
      --token)
        TOKEN="${2:?--token needs a value}"; shift 2 ;;
      -h|--help)
        usage; exit 0 ;;
      *)
        echo "unknown arg: $1" >&2
        usage >&2
        exit 1 ;;
    esac
  done
}

do_get_token() {
  parse_common_args "$@"
  [ -n "$AUTH_USER" ] || { echo "set --user or RINGO_USER" >&2; exit 1; }

  if [ -z "$PASS" ]; then
    printf 'Password: ' >&2
    IFS= read -rs PASS
    printf '\n' >&2
  fi
  [ -n "$PASS" ] || { echo "password is empty" >&2; exit 1; }

  if [ -z "$TOTP" ]; then
    printf 'TOTP (Enter to skip): ' >&2
    IFS= read -r TOTP || true
  fi

  local token
  token=$(enroll_auth "$RINGO" "$AUTH_USER" "$PASS" "$TOTP")
  [ -n "$token" ] && [ "$token" != "null" ] || { echo "enroll/auth: empty access_token" >&2; exit 1; }
  printf '%s\n' "$token"
}

do_install() {
  # elevate before parsing? Need args preserved — elevate first with "$@"
  if [ "$(id -u)" -ne 0 ]; then
    exec sudo -E "$0" install "$@"
  fi

  parse_common_args "$@"

  if [ -z "$TOKEN" ]; then
    [ -n "$AUTH_USER" ] || { echo "set --token, or --user/--pass" >&2; exit 1; }
    [ -n "$PASS" ] || { echo "set --token, or --pass / RINGO_PASS" >&2; exit 1; }
    TOKEN=$(enroll_auth "$RINGO" "$AUTH_USER" "$PASS" "$TOTP")
    [ -n "$TOKEN" ] && [ "$TOKEN" != "null" ] || { echo "enroll/auth: empty access_token" >&2; exit 1; }
  fi

  if systemctl is-active ringo-agent >/dev/null 2>&1; then
    echo "ringo-agent already running"
    exit 0
  fi

  command -v unzip >/dev/null 2>&1 || { echo "unzip is required" >&2; exit 1; }

  WORKDIR=$(mktemp -d)
  trap 'rm -rf "$WORKDIR"' EXIT

  curl -fsS -H "X-Auth-Token: $TOKEN" \
    "$RINGO/agent/enroll?os_type=linux" \
    -o "$WORKDIR/ringo.zip"

  unzip -q "$WORKDIR/ringo.zip" -d "$WORKDIR"

  # service.sh contains: updater install --url <SERVER_URL> --challenge <CHALLENGE>
  local parsed
  parsed="$(sed -nE 's/.*--url[[:space:]]+([^[:space:]]+)[[:space:]]+--challenge[[:space:]]+([^[:space:]]+).*/\1 \2/p' "$WORKDIR/service.sh" | sed -n '1p' | tr -d '"')"
  [ -n "$parsed" ] || { echo "failed to parse --url/--challenge from service.sh" >&2; exit 1; }
  SERVER_URL="${parsed%% *}"
  CHALLENGE="${parsed##* }"

  case "$(uname -m)" in
    x86_64)        UPDATER="$WORKDIR/updater-amd64" ;;
    aarch64|arm64) UPDATER="$WORKDIR/updater-arm64" ;;
    *) echo "unsupported arch: $(uname -m)"; exit 1 ;;
  esac

  chmod +x "$UPDATER"
  "$UPDATER" install --url "$SERVER_URL" --challenge "$CHALLENGE"
}

cmd="${1:-}"
case "$cmd" in
  get-token|auth)
    shift
    do_get_token "$@"
    ;;
  install)
    shift
    do_install "$@"
    ;;
  -h|--help)
    usage
    ;;
  *)
    # backward compatible: bare flags => install
    do_install "$@"
    ;;
esac
