#!/usr/bin/env bash
# Reset one installed MetaMask Mobile app without rebuilding it.
set -euo pipefail

PLATFORM="${PLATFORM:-ios}"
TARGET="$PWD"
SIMULATOR="${SIM_UDID:-${IOS_SIMULATOR:-booted}}"
ADB_SERIAL_ARG="${ADB_SERIAL:-${ANDROID_SERIAL:-}}"
ADB_BIN="${MM_HARNESS_ADB_PATH:-}"
MM_RESET_TEMP_ROOT=""
MM_RESET_STAGING_DIR=""

while [ "$#" -gt 0 ]; do
  case "$1" in
    --platform) PLATFORM="$2"; shift 2 ;;
    --target) TARGET="$2"; shift 2 ;;
    --simulator) SIMULATOR="$2"; shift 2 ;;
    --adb-serial) ADB_SERIAL_ARG="$2"; shift 2 ;;
    -h|--help)
      printf 'Usage: reset-app-data.sh --platform ios|android [--target <dir>] [--simulator <udid|name>] [--adb-serial <serial>]\n'
      exit 0
      ;;
    *) printf 'reset-app-data: unknown arg: %s\n' "$1" >&2; exit 2 ;;
  esac
done

TARGET="$(cd "$TARGET" && pwd -P)"

reset_ios() {
  local bundle_id="" app_source="" candidate="" staged_app=""
  local temp_root="${TMPDIR:-/tmp}" staging_dir=""
  local -a candidates installed_ids installed_paths

  temp_root="${temp_root%/}"
  [ -n "$temp_root" ] && [ "$temp_root" != "/" ] && [ -d "$temp_root" ] && [ ! -L "$temp_root" ] || {
    printf 'reset-app-data: unsafe temporary directory: %s\n' "$temp_root" >&2
    return 1
  }
  if [ -n "${IOS_BUNDLE_ID:-}" ]; then
    candidates=("$IOS_BUNDLE_ID")
  else
    candidates=("io.metamask.MetaMask" "io.metamask" "io.metamask.MetaMask-Flask" "io.metamask.qa")
  fi
  for candidate in "${candidates[@]}"; do
    if app_source="$(xcrun simctl get_app_container "$SIMULATOR" "$candidate" app 2>/dev/null)"; then
      installed_ids+=("$candidate")
      installed_paths+=("$app_source")
    fi
  done
  if [ "${#installed_ids[@]}" -gt 1 ]; then
    printf 'reset-app-data: multiple MetaMask iOS variants are installed on simulator %s: %s.\n' "$SIMULATOR" "${installed_ids[*]}" >&2
    printf 'Next: set IOS_BUNDLE_ID to the exact variant and retry.\n' >&2
    return 1
  fi
  bundle_id="${installed_ids[0]:-}"
  app_source="${installed_paths[0]:-}"
  [ -n "$bundle_id" ] && [ -n "$app_source" ] || {
    printf 'reset-app-data: no installed MetaMask app was found on iOS simulator %s.\n' "$SIMULATOR" >&2
    printf "Next: mm-harness launch --adapter mobile --platform ios --target '%s'\n" "$TARGET" >&2
    return 1
  }
  case "$app_source" in
    */Library/Developer/CoreSimulator/Devices/*/data/Containers/Bundle/Application/*/*.app) ;;
    *) printf 'reset-app-data: refusing unexpected iOS app path: %s\n' "$app_source" >&2; return 1 ;;
  esac
  [ -d "$app_source" ] && [ ! -L "$app_source" ] || {
    printf 'reset-app-data: iOS app is not a real directory: %s\n' "$app_source" >&2
    return 1
  }

  staging_dir="$(mktemp -d "$temp_root/mm-harness-ios-reset.XXXXXX")"
  case "$staging_dir" in
    "$temp_root"/mm-harness-ios-reset.*) ;;
    *) printf 'reset-app-data: refusing unexpected staging path: %s\n' "$staging_dir" >&2; return 1 ;;
  esac
  [ -d "$staging_dir" ] && [ ! -L "$staging_dir" ] || return 1
  staged_app="$staging_dir/$(basename "$app_source")"
  MM_RESET_TEMP_ROOT="$temp_root"
  MM_RESET_STAGING_DIR="$staging_dir"
  cleanup_staging() {
    case "$MM_RESET_STAGING_DIR" in
      "$MM_RESET_TEMP_ROOT"/mm-harness-ios-reset.*)
        [ -d "$MM_RESET_STAGING_DIR" ] && [ ! -L "$MM_RESET_STAGING_DIR" ] && rm -r -- "$MM_RESET_STAGING_DIR"
        ;;
      *) printf 'reset-app-data: staging cleanup refused: %s\n' "$MM_RESET_STAGING_DIR" >&2 ;;
    esac
  }
  trap cleanup_staging EXIT HUP INT TERM

  ditto "$app_source" "$staged_app"
  [ -d "$staged_app" ] && [ ! -L "$staged_app" ] || {
    printf 'reset-app-data: failed to preserve the installed iOS app.\n' >&2
    return 1
  }
  printf 'Resetting iOS app data: simulator=%s bundle=%s\n' "$SIMULATOR" "$bundle_id" >&2
  xcrun simctl terminate "$SIMULATOR" "$bundle_id" >/dev/null 2>&1 || true
  xcrun simctl uninstall "$SIMULATOR" "$bundle_id"
  xcrun simctl install "$SIMULATOR" "$staged_app"
  xcrun simctl get_app_container "$SIMULATOR" "$bundle_id" app >/dev/null
  printf 'Mobile app data reset; preserved installed iOS build %s.\n' "$bundle_id" >&2
}

reset_android() {
  local package_id="" candidate="" clear_output=""
  local -a candidates adb_target installed_ids
  if [ -z "$ADB_BIN" ]; then
    ADB_BIN="$(command -v adb 2>/dev/null || true)"
  fi
  [ -n "$ADB_BIN" ] && [ "${ADB_BIN#/}" != "$ADB_BIN" ] && [ -x "$ADB_BIN" ] || {
    printf 'reset-app-data: Android SDK Platform-Tools (adb) is required.\n' >&2
    printf 'Next: brew install android-platform-tools\n' >&2
    return 1
  }
  [ -n "$ADB_SERIAL_ARG" ] || {
    printf 'reset-app-data: an Android serial is required.\n' >&2
    printf 'Next: mm-harness devices --adapter mobile --json\n' >&2
    return 1
  }
  adb_target=(-s "$ADB_SERIAL_ARG")
  if [ -n "${ANDROID_PACKAGE_ID:-}" ]; then
    candidates=("$ANDROID_PACKAGE_ID")
  else
    candidates=("io.metamask" "io.metamask.flask" "io.metamask.qa")
  fi
  for candidate in "${candidates[@]}"; do
    if "$ADB_BIN" "${adb_target[@]}" shell pm path "$candidate" 2>/dev/null | grep -q '^package:'; then
      installed_ids+=("$candidate")
    fi
  done
  if [ "${#installed_ids[@]}" -gt 1 ]; then
    printf 'reset-app-data: multiple MetaMask Android variants are installed on device %s: %s.\n' "$ADB_SERIAL_ARG" "${installed_ids[*]}" >&2
    printf 'Next: set ANDROID_PACKAGE_ID to the exact variant and retry.\n' >&2
    return 1
  fi
  package_id="${installed_ids[0]:-}"
  [ -n "$package_id" ] || {
    printf 'reset-app-data: no installed MetaMask app was found on Android device %s.\n' "$ADB_SERIAL_ARG" >&2
    printf "Next: mm-harness launch --adapter mobile --platform android --target '%s' --device '%s'\n" "$TARGET" "$ADB_SERIAL_ARG" >&2
    return 1
  }
  printf 'Resetting Android app data: device=%s package=%s\n' "$ADB_SERIAL_ARG" "$package_id" >&2
  clear_output="$("$ADB_BIN" "${adb_target[@]}" shell pm clear "$package_id")"
  [ "$clear_output" = "Success" ] || {
    printf 'reset-app-data: Android package clear failed: %s\n' "$clear_output" >&2
    return 1
  }
  printf 'Mobile app data reset; preserved installed Android build %s.\n' "$package_id" >&2
}

case "$PLATFORM" in
  ios) reset_ios ;;
  android) reset_android ;;
  *) printf 'reset-app-data: --platform must be ios or android (got: %s)\n' "$PLATFORM" >&2; exit 2 ;;
esac
