#!/usr/bin/env bash
# Simulate Android device remote-access heartbeats (type: ra) from Linux CLI.
#
# Usage:
#   ./scripts/ra_device_sim.sh disable
#   ./scripts/ra_device_sim.sh enable --once
#   ./scripts/ra_device_sim.sh poll --until connect
#   CRASHES_BASE=https://apps.f0xx.org/.../crashes ./scripts/ra_device_sim.sh poll --until connect --apply-wg
#
# Env: CRASHES_BASE, RA_DEVICE_ID, RA_RANDOM_FILE, RA_APP_VERSION
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
# shellcheck source=ra_lib.sh
source "$ROOT/scripts/ra_lib.sh"

DEVICE_ID="${RA_DEVICE_ID:-ra-cli-$(hostname -s | tr ' ' '-')}"
RANDOM_FILE="${RA_RANDOM_FILE:-/tmp/androidcast-ra-${DEVICE_ID}.random}"
APP_VERSION="${RA_APP_VERSION:-cli-sim/1.0}"
APPLY_WG=0
POLL_UNTIL=""
ONCE=0
CMD="${1:-help}"
shift || true

while [[ $# -gt 0 ]]; do
  case "$1" in
    --device-id) DEVICE_ID="$2"; shift 2 ;;
    --random-file) RANDOM_FILE="$2"; shift 2 ;;
    --app-version) APP_VERSION="$2"; shift 2 ;;
    --apply-wg) APPLY_WG=1; shift ;;
    --once) ONCE=1; shift ;;
    --until) POLL_UNTIL="$2"; shift 2 ;;
    --base) export CRASHES_BASE="$2"; shift 2 ;;
    -h|--help) CMD=help; shift ;;
    *) echo "Unknown option: $1" >&2; exit 2 ;;
  esac
done

load_random() {
  if [[ -f "$RANDOM_FILE" ]]; then
    cat "$RANDOM_FILE"
  else
    openssl rand -hex 16 2>/dev/null || date +%s
  fi
}

save_random() {
  local r="$1"
  echo "$r" >"$RANDOM_FILE"
}

usage() {
  cat <<'EOF'
AndroidCast remote-access device simulator (heartbeat type: ra)

Commands:
  disable          POST status:disable (like app "Disabled" mode)
  enable           POST status:enable once
  poll             Poll enable; use --until connect|wait|disabled|deny
  show-random      Print persisted device random (like AppPreferences)

Options:
  --base URL       CRASHES_BASE (default local orchestration crashes URL)
  --device-id ID   Stable device_id (default ra-cli-<hostname>)
  --random-file F  Persist random across polls (like app prefs)
  --app-version V  Sent as app_version on heartbeat
  --apply-wg       On connect: write wg-quick conf and run wg-quick up (needs root)
  --once           Single poll (default for enable/poll)
  --until ACTION   Stop polling when heartbeat.action matches (poll mode)

Examples:
  ./scripts/ra_device_sim.sh disable
  ./scripts/ra_device_sim.sh enable --once
  ./scripts/ra_device_sim.sh poll --until connect
  CRASHES_BASE=https://apps.f0xx.org/app/androidcast_project/crashes \
    ./scripts/ra_device_sim.sh poll --until connect --apply-wg
EOF
}

cmd_disable() {
  local rnd
  rnd="$(load_random)"
  save_random "$rnd"
  echo "== ra disable device_id=$DEVICE_ID random=$rnd"
  local resp action
  resp="$(ra_ra_post disable "$DEVICE_ID" "$rnd" "$APP_VERSION")"
  action="$(echo "$resp" | ra_json -r '.heartbeat.action // empty')"
  echo "action=$action"
  echo "$resp" | ra_json '.' 2>/dev/null || echo "$resp"
}

cmd_enable_once() {
  local rnd
  rnd="$(load_random)"
  save_random "$rnd"
  echo "== ra enable device_id=$DEVICE_ID random=$rnd"
  local resp action
  resp="$(ra_ra_post enable "$DEVICE_ID" "$rnd" "$APP_VERSION")"
  action="$(echo "$resp" | ra_json -r '.heartbeat.action // empty')"
  echo "action=$action"
  echo "$resp" | ra_json '.' 2>/dev/null || echo "$resp"
}

cmd_poll() {
  local until="${POLL_UNTIL:-connect}"
  local rnd
  rnd="$(load_random)"
  save_random "$rnd"
  echo "== ra poll until action=$until (device_id=$DEVICE_ID)"
  while true; do
    local resp action
    resp="$(ra_ra_post enable "$DEVICE_ID" "$rnd" "$APP_VERSION")"
    action="$(echo "$resp" | ra_json -r '.heartbeat.action // empty')"
    echo "$(date -Is) action=$action"
    if [[ "$action" == "$until" ]]; then
      echo "$resp" | ra_json '.' 2>/dev/null || echo "$resp"
      if [[ "$action" == "connect" && "$APPLY_WG" -eq 1 ]]; then
        apply_wg "$resp"
      fi
      return 0
    fi
    if [[ "$ONCE" -eq 1 ]]; then
      echo "$resp" | ra_json '.' 2>/dev/null || echo "$resp"
      return 0
    fi
    sleep "${RA_POLL_INTERVAL_S:-3}"
  done
}

apply_wg() {
  local resp="$1"
  if ! command -v wg-quick >/dev/null 2>&1; then
    echo "WARN: wg-quick not installed; skipping tunnel bring-up" >&2
    ra_wg_quick_from_connect "$resp" >"/tmp/ra-${DEVICE_ID}.conf"
    echo "Wrote /tmp/ra-${DEVICE_ID}.conf"
    return 0
  fi
  local conf="/tmp/ra-${DEVICE_ID}.conf"
  ra_wg_quick_from_connect "$resp" >"$conf"
  echo "== wg-quick up $conf (sudo)"
  sudo wg-quick up "$conf" || {
    echo "FAIL: wg-quick up (run as root or check endpoint UDP)" >&2
    return 1
  }
  wg show 2>/dev/null | head -20 || true
}

case "$CMD" in
  disable) cmd_disable ;;
  enable) ONCE=1; cmd_enable_once ;;
  poll) cmd_poll ;;
  show-random) load_random; echo ;;
  help|-h|--help) usage ;;
  *)
    echo "Unknown command: $CMD" >&2
    usage
    exit 2
    ;;
esac
