// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:io';
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

import 'binding.dart';
import 'test_async_utils.dart';
import 'widget_tester.dart';

// A tuple of `key` and `location` from Web's `KeyboardEvent` class.
//
// See [RawKeyEventDataWeb]'s `key` and `location` fields for details.
@immutable
class _WebKeyLocationPair {
  const _WebKeyLocationPair(this.key, this.location);
  final String key;
  final int location;
}

// TODO(gspencergoog): Replace this with more robust key simulation code once
// the new key event code is in.
// https://github.com/flutter/flutter/issues/33521
// This code can only simulate keys which appear in the key maps.

String? _keyLabel(LogicalKeyboardKey key) {
  final String keyLabel = key.keyLabel;
  if (keyLabel.length == 1)
    return keyLabel.toLowerCase();
  return null;
}

// ignore: avoid_classes_with_only_static_members
/// A class that serves as a namespace for a bunch of keyboard-key generation
/// utilities.
class KeyEventSimulator {
  // This class is not meant to be instantiated or extended; this constructor
  // prevents instantiation and extension.
  KeyEventSimulator._();

  // Look up a synonym key, and just return the left version of it.
  static LogicalKeyboardKey _getKeySynonym(LogicalKeyboardKey origKey) {
    if (origKey == LogicalKeyboardKey.shift) {
      return LogicalKeyboardKey.shiftLeft;
    }
    if (origKey == LogicalKeyboardKey.alt) {
      return LogicalKeyboardKey.altLeft;
    }
    if (origKey == LogicalKeyboardKey.meta) {
      return LogicalKeyboardKey.metaLeft;
    }
    if (origKey == LogicalKeyboardKey.control) {
      return LogicalKeyboardKey.controlLeft;
    }
    return origKey;
  }

  static bool _osIsSupported(String platform) {
    switch (platform) {
      case 'android':
      case 'fuchsia':
      case 'macos':
      case 'linux':
      case 'web':
      case 'ios':
      case 'windows':
        return true;
    }
    return false;
  }

  static int _getScanCode(PhysicalKeyboardKey key, String platform) {
    assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
    late Map<int, PhysicalKeyboardKey> map;
    switch (platform) {
      case 'android':
        map = kAndroidToPhysicalKey;
        break;
      case 'fuchsia':
        map = kFuchsiaToPhysicalKey;
        break;
      case 'macos':
        map = kMacOsToPhysicalKey;
        break;
      case 'ios':
        map = kIosToPhysicalKey;
        break;
      case 'linux':
        map = kLinuxToPhysicalKey;
        break;
      case 'windows':
        map = kWindowsToPhysicalKey;
        break;
      case 'web':
        // web doesn't have int type code
        return -1;
    }
    int? scanCode;
    for (final int code in map.keys) {
      if (key.usbHidUsage == map[code]!.usbHidUsage) {
        scanCode = code;
        break;
      }
    }
    assert(scanCode != null, 'Physical key for $key not found in $platform scanCode map');
    return scanCode!;
  }

  static int _getKeyCode(LogicalKeyboardKey key, String platform) {
    assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
    if (kIsWeb) {
      // web doesn't have int type code. This check is used to treeshake
      // keyboard map code.
      return -1;
    } else {
      late Map<int, LogicalKeyboardKey> map;
      switch (platform) {
        case 'android':
          map = kAndroidToLogicalKey;
          break;
        case 'fuchsia':
          map = kFuchsiaToLogicalKey;
          break;
        case 'macos':
        // macOS doesn't do key codes, just scan codes.
          return -1;
        case 'ios':
        // iOS doesn't do key codes, just scan codes.
          return -1;
        case 'web':
          // web doesn't have int type code.
          return -1;
        case 'linux':
          map = kGlfwToLogicalKey;
          break;
        case 'windows':
          map = kWindowsToLogicalKey;
          break;
      }
      int? keyCode;
      for (final int code in map.keys) {
        if (key.keyId == map[code]!.keyId) {
          keyCode = code;
          break;
        }
      }
      assert(keyCode != null, 'Key $key not found in $platform keyCode map');
      return keyCode!;
    }
  }

  static PhysicalKeyboardKey _inferPhysicalKey(LogicalKeyboardKey key) {
    PhysicalKeyboardKey? result;
    for (final PhysicalKeyboardKey physicalKey in PhysicalKeyboardKey.knownPhysicalKeys) {
      if (physicalKey.debugName == key.debugName) {
        result = physicalKey;
        break;
      }
    }
    assert(result != null, 'Unable to infer physical key for $key');
    return result!;
  }

  static _WebKeyLocationPair _getWebKeyLocation(LogicalKeyboardKey key, String keyLabel) {
    String? result;
    for (final MapEntry<String, List<LogicalKeyboardKey?>> entry in kWebLocationMap.entries) {
      final int foundIndex = entry.value.indexOf(key);
      // If foundIndex is -1, then the key is not defined in kWebLocationMap.
      // If foundIndex is 0, then the key is in the standard part of the keyboard,
      // but we have to check `keyLabel` to see if it's remapped or modified.
      if (foundIndex != -1 && foundIndex != 0) {
        return _WebKeyLocationPair(entry.key, foundIndex);
      }
    }
    if (keyLabel.isNotEmpty) {
      return _WebKeyLocationPair(keyLabel, 0);
    }
    for (final String code in kWebToLogicalKey.keys) {
      if (key.keyId == kWebToLogicalKey[code]!.keyId) {
        result = code;
        break;
      }
    }
    assert(result != null, 'Key $key not found in web keyCode map');
    return _WebKeyLocationPair(result!, 0);
  }

  static String _getWebCode(PhysicalKeyboardKey key) {
    String? result;
    for (final MapEntry<String, PhysicalKeyboardKey> entry in kWebToPhysicalKey.entries) {
      if (entry.value.usbHidUsage == key.usbHidUsage) {
        result = entry.key;
        break;
      }
    }
    assert(result != null, 'Key $key not found in web code map');
    return result!;
  }

  static PhysicalKeyboardKey _findPhysicalKeyByPlatform(LogicalKeyboardKey key, String platform) {
    assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
    late Map<dynamic, PhysicalKeyboardKey> map;
    if (kIsWeb) {
      // This check is used to treeshake keymap code.
      map = kWebToPhysicalKey;
    } else {
      switch (platform) {
        case 'android':
          map = kAndroidToPhysicalKey;
          break;
        case 'fuchsia':
          map = kFuchsiaToPhysicalKey;
          break;
        case 'macos':
          map = kMacOsToPhysicalKey;
          break;
        case 'ios':
          map = kIosToPhysicalKey;
          break;
        case 'linux':
          map = kLinuxToPhysicalKey;
          break;
        case 'web':
          map = kWebToPhysicalKey;
          break;
        case 'windows':
          map = kWindowsToPhysicalKey;
          break;
      }
    }
    PhysicalKeyboardKey? result;
    for (final PhysicalKeyboardKey physicalKey in map.values) {
      if (key.debugName == physicalKey.debugName) {
        result = physicalKey;
        break;
      }
    }
    assert(result != null, 'Physical key for $key not found in $platform physical key map');
    return result!;
  }

  /// Get a raw key data map given a [LogicalKeyboardKey] and a platform.
  static Map<String, dynamic> getKeyData(
    LogicalKeyboardKey key, {
    required String platform,
    bool isDown = true,
    PhysicalKeyboardKey? physicalKey,
    String? character,
  }) {
    assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');

    key = _getKeySynonym(key);

    // Find a suitable physical key if none was supplied.
    physicalKey ??= _findPhysicalKeyByPlatform(key, platform);

    assert(key.debugName != null);

    final Map<String, dynamic> result = <String, dynamic>{
      'type': isDown ? 'keydown' : 'keyup',
      'keymap': platform,
    };

    final String resultCharacter = character ?? _keyLabel(key) ?? '';
    void assignWeb() {
      final _WebKeyLocationPair keyLocation = _getWebKeyLocation(key, resultCharacter);
      final PhysicalKeyboardKey actualPhysicalKey = physicalKey ?? _inferPhysicalKey(key);
      result['code'] = _getWebCode(actualPhysicalKey);
      result['key'] = keyLocation.key;
      result['location'] = keyLocation.location;
      result['metaState'] = _getWebModifierFlags(key, isDown);
    }
    if (kIsWeb) {
      assignWeb();
      return result;
    }
    final int keyCode = _getKeyCode(key, platform);
    final int scanCode = _getScanCode(physicalKey, platform);

    switch (platform) {
      case 'android':
        result['keyCode'] = keyCode;
        if (resultCharacter.isNotEmpty) {
          result['codePoint'] = resultCharacter.codeUnitAt(0);
          result['character'] = resultCharacter;
        }
        result['scanCode'] = scanCode;
        result['metaState'] = _getAndroidModifierFlags(key, isDown);
        break;
      case 'fuchsia':
        result['hidUsage'] = physicalKey.usbHidUsage;
        if (resultCharacter.isNotEmpty) {
          result['codePoint'] = resultCharacter.codeUnitAt(0);
        }
        result['modifiers'] = _getFuchsiaModifierFlags(key, isDown);
        break;
      case 'linux':
        result['toolkit'] = 'glfw';
        result['keyCode'] = keyCode;
        result['scanCode'] = scanCode;
        result['modifiers'] = _getGlfwModifierFlags(key, isDown);
        result['unicodeScalarValues'] = resultCharacter.isNotEmpty ? resultCharacter.codeUnitAt(0) : 0;
        break;
      case 'macos':
        result['keyCode'] = scanCode;
        if (resultCharacter.isNotEmpty) {
          result['characters'] = resultCharacter;
          result['charactersIgnoringModifiers'] = resultCharacter;
        }
        result['modifiers'] = _getMacOsModifierFlags(key, isDown);
        break;
      case 'ios':
        result['keyCode'] = scanCode;
        result['characters'] = resultCharacter;
        result['charactersIgnoringModifiers'] = resultCharacter;
        result['modifiers'] = _getIOSModifierFlags(key, isDown);
        break;
      case 'windows':
        result['keyCode'] = keyCode;
        result['scanCode'] = scanCode;
        if (resultCharacter.isNotEmpty) {
          result['characterCodePoint'] = resultCharacter.codeUnitAt(0);
        }
        result['modifiers'] = _getWindowsModifierFlags(key, isDown);
        break;
      case 'web':
        assignWeb();
        break;
    }
    return result;
  }

  static int _getAndroidModifierFlags(LogicalKeyboardKey newKey, bool isDown) {
    int result = 0;
    final Set<LogicalKeyboardKey> pressed = RawKeyboard.instance.keysPressed;
    if (isDown) {
      pressed.add(newKey);
    } else {
      pressed.remove(newKey);
    }
    if (pressed.contains(LogicalKeyboardKey.shiftLeft)) {
      result |= RawKeyEventDataAndroid.modifierLeftShift | RawKeyEventDataAndroid.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.shiftRight)) {
      result |= RawKeyEventDataAndroid.modifierRightShift | RawKeyEventDataAndroid.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.metaLeft)) {
      result |= RawKeyEventDataAndroid.modifierLeftMeta | RawKeyEventDataAndroid.modifierMeta;
    }
    if (pressed.contains(LogicalKeyboardKey.metaRight)) {
      result |= RawKeyEventDataAndroid.modifierRightMeta | RawKeyEventDataAndroid.modifierMeta;
    }
    if (pressed.contains(LogicalKeyboardKey.controlLeft)) {
      result |= RawKeyEventDataAndroid.modifierLeftControl | RawKeyEventDataAndroid.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.controlRight)) {
      result |= RawKeyEventDataAndroid.modifierRightControl | RawKeyEventDataAndroid.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.altLeft)) {
      result |= RawKeyEventDataAndroid.modifierLeftAlt | RawKeyEventDataAndroid.modifierAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.altRight)) {
      result |= RawKeyEventDataAndroid.modifierRightAlt | RawKeyEventDataAndroid.modifierAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.fn)) {
      result |= RawKeyEventDataAndroid.modifierFunction;
    }
    if (pressed.contains(LogicalKeyboardKey.scrollLock)) {
      result |= RawKeyEventDataAndroid.modifierScrollLock;
    }
    if (pressed.contains(LogicalKeyboardKey.numLock)) {
      result |= RawKeyEventDataAndroid.modifierNumLock;
    }
    if (pressed.contains(LogicalKeyboardKey.capsLock)) {
      result |= RawKeyEventDataAndroid.modifierCapsLock;
    }
    return result;
  }

  static int _getGlfwModifierFlags(LogicalKeyboardKey newKey, bool isDown) {
    int result = 0;
    final Set<LogicalKeyboardKey> pressed = RawKeyboard.instance.keysPressed;
    if (isDown) {
      pressed.add(newKey);
    } else {
      pressed.remove(newKey);
    }
    if (pressed.contains(LogicalKeyboardKey.shiftLeft) || pressed.contains(LogicalKeyboardKey.shiftRight)) {
      result |= GLFWKeyHelper.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.metaLeft) || pressed.contains(LogicalKeyboardKey.metaRight)) {
      result |= GLFWKeyHelper.modifierMeta;
    }
    if (pressed.contains(LogicalKeyboardKey.controlLeft) || pressed.contains(LogicalKeyboardKey.controlRight)) {
      result |= GLFWKeyHelper.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.altLeft) || pressed.contains(LogicalKeyboardKey.altRight)) {
      result |= GLFWKeyHelper.modifierAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.capsLock)) {
      result |= GLFWKeyHelper.modifierCapsLock;
    }
    return result;
  }

  static int _getWindowsModifierFlags(LogicalKeyboardKey newKey, bool isDown) {
    int result = 0;
    final Set<LogicalKeyboardKey> pressed = RawKeyboard.instance.keysPressed;
    if (isDown) {
      pressed.add(newKey);
    } else {
      pressed.remove(newKey);
    }
    if (pressed.contains(LogicalKeyboardKey.shift)) {
      result |= RawKeyEventDataWindows.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.shiftLeft)) {
      result |= RawKeyEventDataWindows.modifierLeftShift;
    }
    if (pressed.contains(LogicalKeyboardKey.shiftRight)) {
      result |= RawKeyEventDataWindows.modifierRightShift;
    }
    if (pressed.contains(LogicalKeyboardKey.metaLeft)) {
      result |= RawKeyEventDataWindows.modifierLeftMeta;
    }
    if (pressed.contains(LogicalKeyboardKey.metaRight)) {
      result |= RawKeyEventDataWindows.modifierRightMeta;
    }
    if (pressed.contains(LogicalKeyboardKey.control)) {
      result |= RawKeyEventDataWindows.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.controlLeft)) {
      result |= RawKeyEventDataWindows.modifierLeftControl;
    }
    if (pressed.contains(LogicalKeyboardKey.controlRight)) {
      result |= RawKeyEventDataWindows.modifierRightControl;
    }
    if (pressed.contains(LogicalKeyboardKey.alt)) {
      result |= RawKeyEventDataWindows.modifierAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.altLeft)) {
      result |= RawKeyEventDataWindows.modifierLeftAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.altRight)) {
      result |= RawKeyEventDataWindows.modifierRightAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.capsLock)) {
      result |= RawKeyEventDataWindows.modifierCaps;
    }
    if (pressed.contains(LogicalKeyboardKey.numLock)) {
      result |= RawKeyEventDataWindows.modifierNumLock;
    }
    if (pressed.contains(LogicalKeyboardKey.scrollLock)) {
      result |= RawKeyEventDataWindows.modifierScrollLock;
    }
    return result;
  }

  static int _getFuchsiaModifierFlags(LogicalKeyboardKey newKey, bool isDown) {
    int result = 0;
    final Set<LogicalKeyboardKey> pressed = RawKeyboard.instance.keysPressed;
    if (isDown) {
      pressed.add(newKey);
    } else {
      pressed.remove(newKey);
    }
    if (pressed.contains(LogicalKeyboardKey.shiftLeft)) {
      result |= RawKeyEventDataFuchsia.modifierLeftShift;
    }
    if (pressed.contains(LogicalKeyboardKey.shiftRight)) {
      result |= RawKeyEventDataFuchsia.modifierRightShift;
    }
    if (pressed.contains(LogicalKeyboardKey.metaLeft)) {
      result |= RawKeyEventDataFuchsia.modifierLeftMeta;
    }
    if (pressed.contains(LogicalKeyboardKey.metaRight)) {
      result |= RawKeyEventDataFuchsia.modifierRightMeta;
    }
    if (pressed.contains(LogicalKeyboardKey.controlLeft)) {
      result |= RawKeyEventDataFuchsia.modifierLeftControl;
    }
    if (pressed.contains(LogicalKeyboardKey.controlRight)) {
      result |= RawKeyEventDataFuchsia.modifierRightControl;
    }
    if (pressed.contains(LogicalKeyboardKey.altLeft)) {
      result |= RawKeyEventDataFuchsia.modifierLeftAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.altRight)) {
      result |= RawKeyEventDataFuchsia.modifierRightAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.capsLock)) {
      result |= RawKeyEventDataFuchsia.modifierCapsLock;
    }
    return result;
  }

  static int _getWebModifierFlags(LogicalKeyboardKey newKey, bool isDown) {
    int result = 0;
    final Set<LogicalKeyboardKey> pressed = RawKeyboard.instance.keysPressed;
    if (isDown) {
      pressed.add(newKey);
    } else {
      pressed.remove(newKey);
    }
    if (pressed.contains(LogicalKeyboardKey.shiftLeft)) {
      result |= RawKeyEventDataWeb.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.shiftRight)) {
      result |= RawKeyEventDataWeb.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.metaLeft)) {
      result |= RawKeyEventDataWeb.modifierMeta;
    }
    if (pressed.contains(LogicalKeyboardKey.metaRight)) {
      result |= RawKeyEventDataWeb.modifierMeta;
    }
    if (pressed.contains(LogicalKeyboardKey.controlLeft)) {
      result |= RawKeyEventDataWeb.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.controlRight)) {
      result |= RawKeyEventDataWeb.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.altLeft)) {
      result |= RawKeyEventDataWeb.modifierAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.altRight)) {
      result |= RawKeyEventDataWeb.modifierAlt;
    }
    if (pressed.contains(LogicalKeyboardKey.capsLock)) {
      result |= RawKeyEventDataWeb.modifierCapsLock;
    }
    if (pressed.contains(LogicalKeyboardKey.numLock)) {
      result |= RawKeyEventDataWeb.modifierNumLock;
    }
    if (pressed.contains(LogicalKeyboardKey.scrollLock)) {
      result |= RawKeyEventDataWeb.modifierScrollLock;
    }
    return result;
  }

  static int _getMacOsModifierFlags(LogicalKeyboardKey newKey, bool isDown) {
    int result = 0;
    final Set<LogicalKeyboardKey> pressed = RawKeyboard.instance.keysPressed;
    if (isDown) {
      pressed.add(newKey);
    } else {
      pressed.remove(newKey);
    }
    if (pressed.contains(LogicalKeyboardKey.shiftLeft)) {
      result |= RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.shiftRight)) {
      result |= RawKeyEventDataMacOs.modifierRightShift | RawKeyEventDataMacOs.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.metaLeft)) {
      result |= RawKeyEventDataMacOs.modifierLeftCommand | RawKeyEventDataMacOs.modifierCommand;
    }
    if (pressed.contains(LogicalKeyboardKey.metaRight)) {
      result |= RawKeyEventDataMacOs.modifierRightCommand | RawKeyEventDataMacOs.modifierCommand;
    }
    if (pressed.contains(LogicalKeyboardKey.controlLeft)) {
      result |= RawKeyEventDataMacOs.modifierLeftControl | RawKeyEventDataMacOs.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.controlRight)) {
      result |= RawKeyEventDataMacOs.modifierRightControl | RawKeyEventDataMacOs.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.altLeft)) {
      result |= RawKeyEventDataMacOs.modifierLeftOption | RawKeyEventDataMacOs.modifierOption;
    }
    if (pressed.contains(LogicalKeyboardKey.altRight)) {
      result |= RawKeyEventDataMacOs.modifierRightOption | RawKeyEventDataMacOs.modifierOption;
    }
    final Set<LogicalKeyboardKey> functionKeys = <LogicalKeyboardKey>{
      LogicalKeyboardKey.f1,
      LogicalKeyboardKey.f2,
      LogicalKeyboardKey.f3,
      LogicalKeyboardKey.f4,
      LogicalKeyboardKey.f5,
      LogicalKeyboardKey.f6,
      LogicalKeyboardKey.f7,
      LogicalKeyboardKey.f8,
      LogicalKeyboardKey.f9,
      LogicalKeyboardKey.f10,
      LogicalKeyboardKey.f11,
      LogicalKeyboardKey.f12,
      LogicalKeyboardKey.f13,
      LogicalKeyboardKey.f14,
      LogicalKeyboardKey.f15,
      LogicalKeyboardKey.f16,
      LogicalKeyboardKey.f17,
      LogicalKeyboardKey.f18,
      LogicalKeyboardKey.f19,
      LogicalKeyboardKey.f20,
      LogicalKeyboardKey.f21,
    };
    if (pressed.intersection(functionKeys).isNotEmpty) {
      result |= RawKeyEventDataMacOs.modifierFunction;
    }
    if (pressed.intersection(kMacOsNumPadMap.values.toSet()).isNotEmpty) {
      result |= RawKeyEventDataMacOs.modifierNumericPad;
    }
    if (pressed.contains(LogicalKeyboardKey.capsLock)) {
      result |= RawKeyEventDataMacOs.modifierCapsLock;
    }
    return result;
  }

  static int _getIOSModifierFlags(LogicalKeyboardKey newKey, bool isDown) {
    int result = 0;
    final Set<LogicalKeyboardKey> pressed = RawKeyboard.instance.keysPressed;
    if (isDown) {
      pressed.add(newKey);
    } else {
      pressed.remove(newKey);
    }
    if (pressed.contains(LogicalKeyboardKey.shiftLeft)) {
      result |= RawKeyEventDataIos.modifierLeftShift | RawKeyEventDataIos.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.shiftRight)) {
      result |= RawKeyEventDataIos.modifierRightShift | RawKeyEventDataIos.modifierShift;
    }
    if (pressed.contains(LogicalKeyboardKey.metaLeft)) {
      result |= RawKeyEventDataIos.modifierLeftCommand | RawKeyEventDataIos.modifierCommand;
    }
    if (pressed.contains(LogicalKeyboardKey.metaRight)) {
      result |= RawKeyEventDataIos.modifierRightCommand | RawKeyEventDataIos.modifierCommand;
    }
    if (pressed.contains(LogicalKeyboardKey.controlLeft)) {
      result |= RawKeyEventDataIos.modifierLeftControl | RawKeyEventDataIos.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.controlRight)) {
      result |= RawKeyEventDataIos.modifierRightControl | RawKeyEventDataIos.modifierControl;
    }
    if (pressed.contains(LogicalKeyboardKey.altLeft)) {
      result |= RawKeyEventDataIos.modifierLeftOption | RawKeyEventDataIos.modifierOption;
    }
    if (pressed.contains(LogicalKeyboardKey.altRight)) {
      result |= RawKeyEventDataIos.modifierRightOption | RawKeyEventDataIos.modifierOption;
    }
    final Set<LogicalKeyboardKey> functionKeys = <LogicalKeyboardKey>{
      LogicalKeyboardKey.f1,
      LogicalKeyboardKey.f2,
      LogicalKeyboardKey.f3,
      LogicalKeyboardKey.f4,
      LogicalKeyboardKey.f5,
      LogicalKeyboardKey.f6,
      LogicalKeyboardKey.f7,
      LogicalKeyboardKey.f8,
      LogicalKeyboardKey.f9,
      LogicalKeyboardKey.f10,
      LogicalKeyboardKey.f11,
      LogicalKeyboardKey.f12,
      LogicalKeyboardKey.f13,
      LogicalKeyboardKey.f14,
      LogicalKeyboardKey.f15,
      LogicalKeyboardKey.f16,
      LogicalKeyboardKey.f17,
      LogicalKeyboardKey.f18,
      LogicalKeyboardKey.f19,
      LogicalKeyboardKey.f20,
      LogicalKeyboardKey.f21,
    };
    if (pressed.intersection(functionKeys).isNotEmpty) {
      result |= RawKeyEventDataIos.modifierFunction;
    }
    if (pressed.intersection(kMacOsNumPadMap.values.toSet()).isNotEmpty) {
      result |= RawKeyEventDataIos.modifierNumericPad;
    }
    if (pressed.contains(LogicalKeyboardKey.capsLock)) {
      result |= RawKeyEventDataIos.modifierCapsLock;
    }
    return result;
  }

  static Future<bool> _simulateKeyEventByRawEvent(ValueGetter<Map<String, dynamic>> buildKeyData) async {
    return TestAsyncUtils.guard<bool>(() async {
      final Completer<bool> result = Completer<bool>();
      await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
        SystemChannels.keyEvent.name,
        SystemChannels.keyEvent.codec.encodeMessage(buildKeyData()),
        (ByteData? data) {
          if (data == null) {
            result.complete(false);
            return;
          }
          final Map<String, Object?> decoded = SystemChannels.keyEvent.codec.decodeMessage(data)! as Map<String, dynamic>;
          result.complete(decoded['handled']! as bool);
        }
      );
      return result.future;
    });
  }

  static late final Map<String, PhysicalKeyboardKey> _debugNameToPhysicalKey = (() {
    final Map<String, PhysicalKeyboardKey> result = <String, PhysicalKeyboardKey>{};
    for (final PhysicalKeyboardKey key in PhysicalKeyboardKey.knownPhysicalKeys) {
      final String? debugName = key.debugName;
      if (debugName != null)
        result[debugName] = key;
    }
    return result;
  })();
  static PhysicalKeyboardKey _findPhysicalKey(LogicalKeyboardKey key) {
    final PhysicalKeyboardKey? result = _debugNameToPhysicalKey[key.debugName];
    assert(result != null, 'Physical key for $key not found in known physical keys');
    return result!;
  }

  static const KeyDataTransitMode _defaultTransitMode = KeyDataTransitMode.rawKeyData;

  // The simulation transit mode for [simulateKeyDownEvent], [simulateKeyUpEvent],
  // and [simulateKeyRepeatEvent].
  //
  // Simulation transit mode is the mode that simulated key events are constructed
  // and delivered. For detailed introduction, see [KeyDataTransitMode] and
  // its values.
  //
  // The `_transitMode` defaults to [KeyDataTransitMode.rawKeyEvent], and can be
  // overridden with [debugKeyEventSimulatorTransitModeOverride].  In widget tests, it
  // is often set with [KeySimulationModeVariant].
  static KeyDataTransitMode get _transitMode {
    KeyDataTransitMode? result;
    assert(() {
      result = debugKeyEventSimulatorTransitModeOverride;
      return true;
    }());
    return result ?? _defaultTransitMode;
  }

  static String get _defaultPlatform => kIsWeb ? 'web' : Platform.operatingSystem;

  /// Simulates sending a hardware key down event.
  ///
  /// This only simulates key presses coming from a physical keyboard, not from a
  /// soft keyboard.
  ///
  /// Specify `platform` as one of the platforms allowed in
  /// [Platform.operatingSystem] to make the event appear to be from that type of
  /// system. Defaults to the operating system that the test is running on. Some
  /// platforms (e.g. Windows, iOS) are not yet supported.
  ///
  /// Keys that are down when the test completes are cleared after each test.
  ///
  /// Returns true if the key event was handled by the framework.
  ///
  /// See also:
  ///
  ///  * [simulateKeyUpEvent] to simulate the corresponding key up event.
  static Future<bool> simulateKeyDownEvent(
    LogicalKeyboardKey key, {
    String? platform,
    PhysicalKeyboardKey? physicalKey,
    String? character,
  }) async {
    Future<bool> _simulateByRawEvent() {
      return _simulateKeyEventByRawEvent(() {
        platform ??= _defaultPlatform;
        return getKeyData(key, platform: platform!, physicalKey: physicalKey, character: character);
      });
    }
    switch (_transitMode) {
      case KeyDataTransitMode.rawKeyData:
        return _simulateByRawEvent();
      case KeyDataTransitMode.keyDataThenRawKeyData:
        final LogicalKeyboardKey logicalKey = _getKeySynonym(key);
        final bool resultByKeyEvent = ServicesBinding.instance!.keyEventManager.handleKeyData(
          ui.KeyData(
            type: ui.KeyEventType.down,
            physical: (physicalKey ?? _findPhysicalKey(logicalKey)).usbHidUsage,
            logical: logicalKey.keyId,
            timeStamp: Duration.zero,
            character: character ?? _keyLabel(key),
            synthesized: false,
          ),
        );
        return (await _simulateByRawEvent()) || resultByKeyEvent;
    }
  }

  /// Simulates sending a hardware key up event through the system channel.
  ///
  /// This only simulates key presses coming from a physical keyboard, not from a
  /// soft keyboard.
  ///
  /// Specify `platform` as one of the platforms allowed in
  /// [Platform.operatingSystem] to make the event appear to be from that type of
  /// system. Defaults to the operating system that the test is running on. Some
  /// platforms (e.g. Windows, iOS) are not yet supported.
  ///
  /// Returns true if the key event was handled by the framework.
  ///
  /// See also:
  ///
  ///  * [simulateKeyDownEvent] to simulate the corresponding key down event.
  static Future<bool> simulateKeyUpEvent(
    LogicalKeyboardKey key, {
    String? platform,
    PhysicalKeyboardKey? physicalKey,
  }) async {
    Future<bool> _simulateByRawEvent() {
      return _simulateKeyEventByRawEvent(() {
        platform ??= _defaultPlatform;
        return getKeyData(key, platform: platform!, isDown: false, physicalKey: physicalKey);
      });
    }
    switch (_transitMode) {
      case KeyDataTransitMode.rawKeyData:
        return _simulateByRawEvent();
      case KeyDataTransitMode.keyDataThenRawKeyData:
        final LogicalKeyboardKey logicalKey = _getKeySynonym(key);
        final bool resultByKeyEvent = ServicesBinding.instance!.keyEventManager.handleKeyData(
          ui.KeyData(
            type: ui.KeyEventType.up,
            physical: (physicalKey ?? _findPhysicalKey(logicalKey)).usbHidUsage,
            logical: logicalKey.keyId,
            timeStamp: Duration.zero,
            character: null,
            synthesized: false,
          ),
        );
        return (await _simulateByRawEvent()) || resultByKeyEvent;
    }
  }

  /// Simulates sending a hardware key repeat event through the system channel.
  ///
  /// This only simulates key presses coming from a physical keyboard, not from a
  /// soft keyboard.
  ///
  /// Specify `platform` as one of the platforms allowed in
  /// [Platform.operatingSystem] to make the event appear to be from that type of
  /// system. Defaults to the operating system that the test is running on. Some
  /// platforms (e.g. Windows, iOS) are not yet supported.
  ///
  /// Returns true if the key event was handled by the framework.
  ///
  /// See also:
  ///
  ///  * [simulateKeyDownEvent] to simulate the corresponding key down event.
  static Future<bool> simulateKeyRepeatEvent(
    LogicalKeyboardKey key, {
    String? platform,
    PhysicalKeyboardKey? physicalKey,
    String? character,
  }) async {
    Future<bool> _simulateByRawEvent() {
      return _simulateKeyEventByRawEvent(() {
        platform ??= _defaultPlatform;
        return getKeyData(key, platform: platform!, physicalKey: physicalKey, character: character);
      });
    }
    switch (_transitMode) {
      case KeyDataTransitMode.rawKeyData:
        return _simulateByRawEvent();
      case KeyDataTransitMode.keyDataThenRawKeyData:
        final LogicalKeyboardKey logicalKey = _getKeySynonym(key);
        final bool resultByKeyEvent = ServicesBinding.instance!.keyEventManager.handleKeyData(
          ui.KeyData(
            type: ui.KeyEventType.repeat,
            physical: (physicalKey ?? _findPhysicalKey(logicalKey)).usbHidUsage,
            logical: logicalKey.keyId,
            timeStamp: Duration.zero,
            character: character ?? _keyLabel(key),
            synthesized: false,
          ),
        );
        return (await _simulateByRawEvent()) || resultByKeyEvent;
    }
  }
}

/// Simulates sending a hardware key down event through the system channel.
///
/// It is intended for use in writing tests.
///
/// This only simulates key presses coming from a physical keyboard, not from a
/// soft keyboard, and it can only simulate keys that appear in the key maps
/// such as [kAndroidToLogicalKey], [kMacOsToPhysicalKey], etc.
///
/// Specify `platform` as one of the platforms allowed in
/// [Platform.operatingSystem] to make the event appear to be from that type of
/// system. Defaults to the operating system that the test is running on. Some
/// platforms (e.g. Windows, iOS) are not yet supported.
///
/// Keys that are down when the test completes are cleared after each test.
///
/// Returns true if the key event was handled by the framework.
///
/// See also:
///
///  * [simulateKeyUpEvent] and [simulateKeyRepeatEvent] to simulate the
///    corresponding key up and repeat event.
Future<bool> simulateKeyDownEvent(
  LogicalKeyboardKey key, {
  String? platform,
  PhysicalKeyboardKey? physicalKey,
  String? character,
}) {
  return KeyEventSimulator.simulateKeyDownEvent(key, platform: platform, physicalKey: physicalKey, character: character);
}

/// Simulates sending a hardware key up event through the system channel.
///
/// It is intended for use in writing tests.
///
/// This only simulates key presses coming from a physical keyboard, not from a
/// soft keyboard, and it can only simulate keys that appear in the key maps
/// such as [kAndroidToLogicalKey], [kMacOsToPhysicalKey], etc.
///
/// Specify `platform` as one of the platforms allowed in
/// [Platform.operatingSystem] to make the event appear to be from that type of
/// system. Defaults to the operating system that the test is running on. Some
/// platforms (e.g. Windows, iOS) are not yet supported.
///
/// Returns true if the key event was handled by the framework.
///
/// See also:
///
///  * [simulateKeyDownEvent] and [simulateKeyRepeatEvent] to simulate the
///    corresponding key down and repeat event.
Future<bool> simulateKeyUpEvent(
  LogicalKeyboardKey key, {
  String? platform,
  PhysicalKeyboardKey? physicalKey,
}) {
  return KeyEventSimulator.simulateKeyUpEvent(key, platform: platform, physicalKey: physicalKey);
}

/// Simulates sending a hardware key repeat event through the system channel.
///
/// This only simulates key presses coming from a physical keyboard, not from a
/// soft keyboard.
///
/// Specify `platform` as one of the platforms allowed in
/// [Platform.operatingSystem] to make the event appear to be from that type of
/// system. Defaults to the operating system that the test is running on. Some
/// platforms (e.g. Windows, iOS) are not yet supported.
///
/// Returns true if the key event was handled by the framework.
///
/// See also:
///
///  - [simulateKeyDownEvent] and [simulateKeyUpEvent] to simulate the
///    corresponding key down and up event.
Future<bool> simulateKeyRepeatEvent(
  LogicalKeyboardKey key, {
  String? platform,
  PhysicalKeyboardKey? physicalKey,
  String? character,
}) {
  return KeyEventSimulator.simulateKeyRepeatEvent(key, platform: platform, physicalKey: physicalKey, character: character);
}

/// A [TestVariant] that runs tests with transit modes set to different values
/// of [KeyDataTransitMode].
class KeySimulatorTransitModeVariant extends TestVariant<KeyDataTransitMode> {
  /// Creates a [KeySimulatorTransitModeVariant] that tests the given [values].
  const KeySimulatorTransitModeVariant(this.values);

  /// Creates a [KeySimulatorTransitModeVariant] for each value option of
  /// [KeyDataTransitMode].
  KeySimulatorTransitModeVariant.all()
    : this(KeyDataTransitMode.values.toSet());

  /// Creates a [KeySimulatorTransitModeVariant] that only contains
  /// [KeyDataTransitMode.keyDataThenRawKeyData].
  KeySimulatorTransitModeVariant.keyDataThenRawKeyData()
    : this(<KeyDataTransitMode>{KeyDataTransitMode.keyDataThenRawKeyData});

  @override
  final Set<KeyDataTransitMode> values;

  @override
  String describeValue(KeyDataTransitMode value) {
    switch (value) {
      case KeyDataTransitMode.rawKeyData:
        return 'RawKeyEvent';
      case KeyDataTransitMode.keyDataThenRawKeyData:
        return 'ui.KeyData then RawKeyEvent';
    }
  }

  @override
  Future<KeyDataTransitMode?> setUp(KeyDataTransitMode value) async {
    final KeyDataTransitMode? previousSetting = debugKeyEventSimulatorTransitModeOverride;
    debugKeyEventSimulatorTransitModeOverride = value;
    return previousSetting;
  }

  @override
  Future<void> tearDown(KeyDataTransitMode value, KeyDataTransitMode? memento) async {
    // ignore: invalid_use_of_visible_for_testing_member
    RawKeyboard.instance.clearKeysPressed();
    // ignore: invalid_use_of_visible_for_testing_member
    HardwareKeyboard.instance.clearState();
    // ignore: invalid_use_of_visible_for_testing_member
    ServicesBinding.instance!.keyEventManager.clearState();
    debugKeyEventSimulatorTransitModeOverride = memento;
  }
}
