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

ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
FLUTTER_DOCKER_SCRIPT="$ROOT_DIR/scripts/flutter-docker.sh"
HOST_ADB_SCRIPT="${TDC114_HOST_ADB_SCRIPT:-$ROOT_DIR/scripts/host-adb.sh}"
LOCAL_ENV_FILE="${TDC114_SMOKE_ENV_FILE:-$ROOT_DIR/scripts/.env.android-device.local}"

if [ -f "$LOCAL_ENV_FILE" ]; then
  # shellcheck disable=SC1090
  source "$LOCAL_ENV_FILE"
fi

ADB_SOCKET="${ADB_SERVER_SOCKET:-}"
DEVICE_ID="${TDC114_FLUTTER_DEVICE_ID:-}"
API_BASE="${TDC114_API_BASE:-}"
AUTH_API_BASE="${TDC114_AUTH_API_BASE:-}"
REVERSE_PORT="${TDC114_ANDROID_REVERSE_PORT:-5000}"
AUTH_REVERSE_PORT="${TDC114_AUTH_ANDROID_REVERSE_PORT:-5001}"

is_reverse_mode() {
  [ "$API_BASE" = "http://127.0.0.1:${REVERSE_PORT}" ]
}

is_auth_reverse_mode() {
  [ "$AUTH_API_BASE" = "http://127.0.0.1:${AUTH_REVERSE_PORT}" ]
}

print_header() {
  echo "[android-device-preflight]"
  if [ -n "$ADB_SOCKET" ]; then
    echo "ADB server socket: $ADB_SOCKET"
  else
    echo "ADB server socket: default container adb server"
  fi
  if [ -n "$DEVICE_ID" ]; then
    echo "Target device id: $DEVICE_ID"
  else
    echo "Target device id: first physical device in adb devices"
  fi
  if [ -n "$API_BASE" ]; then
    echo "TDC114_API_BASE: $API_BASE"
    if is_reverse_mode; then
      echo "Connection mode: local adb-reverse"
    else
      echo "Connection mode: direct HTTPS/LAN"
    fi
  fi
  if [ -n "$AUTH_API_BASE" ]; then
    echo "TDC114_AUTH_API_BASE: $AUTH_API_BASE"
    if is_auth_reverse_mode; then
      echo "Auth connection mode: local adb-reverse"
    else
      echo "Auth connection mode: direct HTTPS/LAN"
    fi
  fi
  echo
}

fail_with_help() {
  local reason="$1"
  print_header
  echo "FAIL $reason"
  echo
  echo "Windows-side checklist:"
  echo "1. Connect the Android phone by USB."
  echo "2. Enable Developer options > USB debugging."
  echo "3. Accept the RSA debugging prompt on the phone."
  echo "4. In Windows PowerShell, run adb.exe devices and confirm the phone is device."
  echo "5. If using local API through adb reverse, run adb reverse tcp:${REVERSE_PORT} tcp:${REVERSE_PORT} from the same ADB server path."
  if is_auth_reverse_mode; then
    echo "   Also run adb reverse tcp:${AUTH_REVERSE_PORT} tcp:${AUTH_REVERSE_PORT} for the local auth server."
  fi
  echo "6. If using direct staging/production HTTPS mode, confirm TDC114_API_BASE points to the public app API host."
  if [ -n "$ADB_SOCKET" ]; then
    echo "7. If WSL reports connection refused to ${ADB_SOCKET}, recreate the Windows 5037 portproxy and firewall rule first."
  fi
  echo
  echo "Recommended WSL command:"
  echo "  ADB_SERVER_SOCKET=tcp:<WINDOWS_HOST_IP>:5037 \\"
  echo "  TDC114_FLUTTER_DEVICE_ID=<PHYSICAL_DEVICE_ID> \\"
  echo "  TDC114_SMOKE_ENV_FILE=scripts/.env.android-device.local \\"
  echo "  ./scripts/manual-postlogin-run.sh"
}

fail_with_adb_help() {
  local reason="$1"
  print_header
  echo "FAIL $reason"
  echo
  echo "WSL host-adb checklist:"
  echo "1. Confirm $HOST_ADB_SCRIPT exists and is executable."
  echo "2. If host adb is missing, run ./scripts/install-host-adb-from-docker.sh once."
  echo "3. Confirm ADB_SERVER_SOCKET points to the Windows ADB server, usually tcp:172.21.128.1:5037."
  echo "4. After host adb access recovers, rerun this script."
  echo
  echo "Recommended WSL command:"
  echo "  ADB_SERVER_SOCKET=tcp:172.21.128.1:5037 ./scripts/host-adb.sh devices"
}

if [ ! -x "$HOST_ADB_SCRIPT" ]; then
  echo "Missing executable script: $HOST_ADB_SCRIPT" >&2
  exit 1
fi

if [[ "$DEVICE_ID" == emulator-* ]]; then
  fail_with_help "TDC114_FLUTTER_DEVICE_ID points to an emulator, not a physical Android device."
  exit 1
fi

env_args=()
if [ -n "$ADB_SOCKET" ]; then
  env_args+=("ADB_SERVER_SOCKET=$ADB_SOCKET")
fi

set +e
if [ "${#env_args[@]}" -gt 0 ]; then
  OUTPUT="$(env "${env_args[@]}" "$HOST_ADB_SCRIPT" devices 2>&1)"
else
  OUTPUT="$("$HOST_ADB_SCRIPT" devices 2>&1)"
fi
STATUS=$?
set -e

if [ "$STATUS" -ne 0 ]; then
  if printf '%s\n' "$OUTPUT" | grep -Fq "Host adb is not available"; then
    fail_with_adb_help "Host adb is not ready."
    printf '%s\n' "$OUTPUT"
    exit "$STATUS"
  fi

  fail_with_help "ADB devices command failed."
  if printf '%s\n' "$OUTPUT" | grep -Fq "Connection refused"; then
    echo
    echo "Hint: Windows ADB itself may be alive, but WSL shared access to port 5037 is blocked."
    echo "Rebuild portproxy: 0.0.0.0:5037 -> 127.0.0.1:5037, then retry."
  fi
  if printf '%s\n' "$OUTPUT" | grep -Fq "protocol fault (couldn't read status)"; then
    echo
    echo "Hint: Windows port 5037 may be owned by portproxy before adb.exe starts."
    echo "In Windows Administrator PowerShell: delete the 5037 portproxy, start adb.exe, confirm adb.exe devices, then recreate the portproxy."
  fi
  if printf '%s\n' "$OUTPUT" | grep -Fq "failed to read response from server"; then
    echo
    echo "Hint: Windows adb.exe may be talking to a stale or non-ADB listener on port 5037."
    echo "In Windows Administrator PowerShell: inspect netstat -ano | findstr 5037 before restarting adb.exe."
  fi
  printf '%s\n' "$OUTPUT"
  exit "$STATUS"
fi

if [ -n "$DEVICE_ID" ]; then
  DEVICE_PATTERN="^${DEVICE_ID}[[:space:]]+device$"
  OFFLINE_PATTERN="^${DEVICE_ID}[[:space:]]+offline$"
  UNAUTHORIZED_PATTERN="^${DEVICE_ID}[[:space:]]+unauthorized$"
else
  DEVICE_PATTERN="^[[:alnum:]_.:-]+[[:space:]]+device$"
  OFFLINE_PATTERN="^[[:alnum:]_.:-]+[[:space:]]+offline$"
  UNAUTHORIZED_PATTERN="^[[:alnum:]_.:-]+[[:space:]]+unauthorized$"
fi

if [ -z "$DEVICE_ID" ]; then
  DETECTED_UNAUTHORIZED_ID="$(printf '%s\n' "$OUTPUT" | awk '$2 == "unauthorized" && $1 !~ /^emulator-/ {print $1; exit}')"
  if [ -n "$DETECTED_UNAUTHORIZED_ID" ]; then
    fail_with_help "Physical Android device is unauthorized."
    printf '%s\n' "$OUTPUT"
    exit 1
  fi

  DETECTED_OFFLINE_ID="$(printf '%s\n' "$OUTPUT" | awk '$2 == "offline" && $1 !~ /^emulator-/ {print $1; exit}')"
  if [ -n "$DETECTED_OFFLINE_ID" ]; then
    fail_with_help "Physical Android device is offline."
    printf '%s\n' "$OUTPUT"
    exit 1
  fi

  DETECTED_DEVICE_ID="$(printf '%s\n' "$OUTPUT" | awk '$2 == "device" && $1 !~ /^emulator-/ {print $1; exit}')"
  if [ -z "$DETECTED_DEVICE_ID" ]; then
    fail_with_help "No usable physical Android device was detected."
    printf '%s\n' "$OUTPUT"
    exit 1
  fi
  DEVICE_ID="$DETECTED_DEVICE_ID"
else
  if printf '%s\n' "$OUTPUT" | grep -Eq "$UNAUTHORIZED_PATTERN"; then
    fail_with_help "Physical Android device is unauthorized."
    printf '%s\n' "$OUTPUT"
    exit 1
  fi

  if printf '%s\n' "$OUTPUT" | grep -Eq "$OFFLINE_PATTERN"; then
    fail_with_help "Physical Android device is offline."
    printf '%s\n' "$OUTPUT"
    exit 1
  fi

  if ! printf '%s\n' "$OUTPUT" | grep -Eq "$DEVICE_PATTERN"; then
    fail_with_help "No usable physical Android device was detected."
    printf '%s\n' "$OUTPUT"
    exit 1
  fi
fi

if [ -z "$DEVICE_ID" ]; then
  fail_with_help "No usable physical Android device was detected."
  printf '%s\n' "$OUTPUT"
  exit 1
fi

if is_reverse_mode || is_auth_reverse_mode; then
  reverse_args=("adb")
  if [ -n "$DEVICE_ID" ]; then
    reverse_args+=("-s" "$DEVICE_ID")
  fi
  reverse_args+=("reverse" "--list")

  set +e
  if [ "${#env_args[@]}" -gt 0 ]; then
    REVERSE_OUTPUT="$(env "${env_args[@]}" "$HOST_ADB_SCRIPT" "${reverse_args[@]:1}" 2>&1)"
  else
    REVERSE_OUTPUT="$("$HOST_ADB_SCRIPT" "${reverse_args[@]:1}" 2>&1)"
  fi
  REVERSE_STATUS=$?
  set -e

  if [ "$REVERSE_STATUS" -ne 0 ]; then
    fail_with_help "adb reverse tcp:${REVERSE_PORT} tcp:${REVERSE_PORT} is not active."
    printf '%s\n' "$OUTPUT"
    printf '%s\n' "$REVERSE_OUTPUT"
    exit 1
  fi
  if is_reverse_mode && ! printf '%s\n' "$REVERSE_OUTPUT" | grep -Fq "tcp:${REVERSE_PORT} tcp:${REVERSE_PORT}"; then
    fail_with_help "adb reverse tcp:${REVERSE_PORT} tcp:${REVERSE_PORT} is not active."
    printf '%s\n' "$OUTPUT"
    printf '%s\n' "$REVERSE_OUTPUT"
    exit 1
  fi
  if is_auth_reverse_mode && ! printf '%s\n' "$REVERSE_OUTPUT" | grep -Fq "tcp:${AUTH_REVERSE_PORT} tcp:${AUTH_REVERSE_PORT}"; then
    fail_with_help "adb reverse tcp:${AUTH_REVERSE_PORT} tcp:${AUTH_REVERSE_PORT} is not active."
    printf '%s\n' "$OUTPUT"
    printf '%s\n' "$REVERSE_OUTPUT"
    exit 1
  fi
fi

print_header
echo "PASS Physical Android device is ready for Docker/WSL Flutter checks."
printf '%s\n' "$OUTPUT"
