#!/data/data/com.termux/files/usr/bin/bash
set -euo pipefail

RED="\033[31m"
YEL="\033[33m"
GRN="\033[32m"
BLU="\033[34m"
RST="\033[0m"
BOLD="\033[1m"

log()      { printf "${BLU}[iiab]${RST} %s\n" "$*"; }
ok()       { printf "${GRN}[iiab]${RST} %s\n" "$*"; }
warn()     { printf "${YEL}[iiab] WARNING:${RST} %s\n" "$*" >&2; }
warn_red() { printf "${RED}${BOLD}[iiab] WARNING:${RST} %s\n" "$*" >&2; }

have() { command -v "$1" >/dev/null 2>&1; }

HOST="127.0.0.1"
CONNECT_PORT=""
TIMEOUT_SECS=180
STATE_DIR="${TMPDIR:-/data/data/com.termux/files/usr/tmp}/adbw_pair"
NOTIF_ID=9400
CLEANUP_OFFLINE=1
DEBUG=0

mkdir -p "$STATE_DIR"

need() { command -v "$1" >/dev/null 2>&1; }
die(){ echo "[!] $*" >&2; exit 1; }
dbg(){ [[ "$DEBUG" == "1" ]] && echo "[DBG] $*" >&2 || true; }

# Avoid dpkg conffile prompts (Termux layer)
TERMUX_APT_OPTS=(
  "-y"
  "-o" "Dpkg::Options::=--force-confdef"
  "-o" "Dpkg::Options::=--force-confold"
)
termux_apt() { apt-get "${TERMUX_APT_OPTS[@]}" "$@"; }

step_termux_repo_select_once() {
  local stamp="$STATE_DIR/stamp.termux_repo_selected"
  if [[ -f "$stamp" ]]; then
    return 0
  fi

  if ! have termux-change-repo; then
    warn "termux-change-repo not found; skipping mirror selection."
    return 0
  fi

  # When running via "curl | bash", stdin is not a TTY.
  # Try to prompt via /dev/tty if available. If not, skip WITHOUT stamping.
  if [[ -r /dev/tty ]]; then
    printf "\n${YEL}[iiab] One-time setup:${RST} Select a nearby Termux repository mirror for faster downloads.\n" >&2

    local ans="Y"
    if ! read -r -p "[iiab] Launch termux-change-repo now? [Y/n]: " ans < /dev/tty; then
      warn "No interactive TTY available; skipping mirror selection (run the script directly to be prompted)."
      return 0
    fi

    ans="${ans:-Y}"
    if [[ "$ans" =~ ^[Yy]$ ]]; then
      termux-change-repo || true
      ok "Mirror selection completed (or skipped inside the UI)."
    else
      warn "Mirror selection skipped by user."
    fi

    date > "$stamp"
    return 0
  fi

  warn "No /dev/tty available; skipping mirror selection (run the script directly to be prompted)."
  return 0
}

install_if_missing() {
  local pkgs=()
  need adb || pkgs+=("android-tools")
  need termux-notification || pkgs+=("termux-api")
  termux_apt update || true
  termux_apt upgrade || true
  if ((${#pkgs[@]})); then
    echo "[*] Installing: ${pkgs[*]}"
    termux_apt install "${pkgs[@]}" >/dev/null
  fi
  need adb || die "Missing adb. Install: pkg install android-tools"
  need termux-notification || die "Missing termux-notification. Install: pkg install termux-api (and install Termux:API app)"
}

cleanup_notif() {
  termux-notification-remove "$NOTIF_ID" >/dev/null 2>&1 || true
}

notify_ask_one() {
  # args: key title content
  local key="$1" title="$2" content="$3"
  local out="$STATE_DIR/$key.txt"
  rm -f "$out"

  # Force a "fresh" notification so Android plays sound each time
  termux-notification-remove "$NOTIF_ID" >/dev/null 2>&1 || true

  termux-notification \
    --id "$NOTIF_ID" \
    --ongoing \
    --alert-once \
    --priority max \
    --title "$title" \
    --content "$content" \
    --sound \
    --button1 "Answer" \
    --button1-action "sh -lc 'echo \"\$REPLY\" > \"$out\"'"

  local start now
  start="$(date +%s)"
  while true; do
    if [[ -s "$out" ]]; then
      tr -d '\r\n' < "$out"
      return 0
    fi
    now="$(date +%s)"
    if (( now - start >= TIMEOUT_SECS )); then
      return 1
    fi
    sleep 1
  done
}

ask_port_5digits() {
  # args: key title
  local key="$1" title="$2"
  local v=""
  while true; do
    v="$(notify_ask_one "$key" "$title" "(5 digits)")" || return 1
    v="${v//[[:space:]]/}"
    [[ "$v" =~ ^[0-9]{5}$ ]] || continue
    echo "$v"
    return 0
  done
}

ask_code_6digits() {
  local v=""
  while true; do
    v="$(notify_ask_one code "PAIR CODE" "(6 digits)")" || return 1
    v="${v//[[:space:]]/}"
    [[ -n "$v" ]] || continue
    [[ "$v" =~ ^[0-9]+$ ]] || continue

    # Allow missing leading zeros, then normalize to exactly 6 digits
    if ((${#v} < 6)); then
      v="$(printf "%06d" "$v")"
    fi

    [[ "$v" =~ ^[0-9]{6}$ ]] || continue
    echo "$v"
    return 0
  done
}

cleanup_offline_loopback() {
  local keep_serial="$1"   # e.g. 127.0.0.1:42371
  local line serial state
  while read -r line; do
    serial="$(echo "$line" | awk '{print $1}')"
    state="$(echo "$line" | awk '{print $2}')"
    [[ "$serial" == ${HOST}:* ]] || continue
    [[ "$state" == "offline" ]] || continue
    [[ "$serial" == "$keep_serial" ]] && continue
    adb disconnect "$serial" >/dev/null 2>&1 || true
  done < <(adb devices 2>/dev/null | tail -n +2 | sed '/^\s*$/d')
}

usage() {
  cat <<EOF
Usage:
  $0 [--connect-port 41313] [--host 127.0.0.1] [--no-cleanup-offline] [--debug]

Prompts:
  CONNECT PORT (5 digits)  # only if --connect-port not provided
  PAIR PORT   (5 digits)
  PAIR CODE   (6 digits)
EOF
}

main() {
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --host) HOST="${2:-}"; shift 2 ;;
      --connect-port) CONNECT_PORT="${2:-}"; shift 2 ;;
      --no-cleanup-offline) CLEANUP_OFFLINE=0; shift ;;
      --debug) DEBUG=1; shift ;;
      -h|--help) usage; exit 0 ;;
      *) die "Unknown arg: $1" ;;
    esac
  done

  install_if_missing
  trap cleanup_notif EXIT

  adb start-server >/dev/null 2>&1 || true
  echo "[*] adb: $(adb version | head -n 1)"

  if [[ -n "$CONNECT_PORT" ]]; then
    CONNECT_PORT="${CONNECT_PORT//[[:space:]]/}"
    [[ "$CONNECT_PORT" =~ ^[0-9]{5}$ ]] || die "Invalid --connect-port (must be 5 digits): '$CONNECT_PORT'"
  else
    echo "[*] Asking CONNECT PORT..."
    CONNECT_PORT="$(ask_port_5digits connect "CONNECT PORT")" || die "Timeout waiting CONNECT PORT."
  fi

  echo "[*] Asking PAIR PORT..."
  local pair_port
  pair_port="$(ask_port_5digits pair "PAIR PORT")" || die "Timeout waiting PAIR PORT."

  echo "[*] Asking PAIR CODE..."
  local code
  code="$(ask_code_6digits)" || die "Timeout waiting PAIR CODE."

  local serial="${HOST}:${CONNECT_PORT}"

  adb disconnect "$serial" >/dev/null 2>&1 || true

  echo "[*] adb pair ${HOST}:${pair_port}"
  printf '%s\n' "$code" | adb pair "${HOST}:${pair_port}"

  echo "[*] adb connect $serial"
  adb connect "$serial" >/dev/null

  if [[ "$CLEANUP_OFFLINE" == "1" ]]; then
    cleanup_offline_loopback "$serial"
  fi

  echo "[*] Devices:"
  adb devices -l

  echo "[*] ADB check (shell):"
  adb -s "$serial" shell sh -lc 'echo "it worked: adb shell is working"; getprop ro.product.model; getprop ro.build.version.release' || true

  echo "[+] OK"
}

main "$@"
