// 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:convert';

import 'utils.dart';

/// The data structure used to manage keyboard key entries.
///
/// The main constructor parses the given input data into the data structure.
///
/// The data structure can be also loaded and saved to JSON, with the
/// [PhysicalKeyData.fromJson] constructor and [toJson] method, respectively.
class PhysicalKeyData {
  factory PhysicalKeyData(
    String chromiumHidCodes,
    String androidKeyboardLayout,
    String androidNameMap,
  ) {
    final Map<String, List<int>> nameToAndroidScanCodes = _readAndroidScanCodes(androidKeyboardLayout, androidNameMap);
    final Map<String, PhysicalKeyEntry> data = _readHidEntries(
      chromiumHidCodes,
      nameToAndroidScanCodes,
    );
    final List<MapEntry<String, PhysicalKeyEntry>> sortedEntries = data.entries.toList()..sort(
      (MapEntry<String, PhysicalKeyEntry> a, MapEntry<String, PhysicalKeyEntry> b) =>
        PhysicalKeyEntry.compareByUsbHidCode(a.value, b.value),
    );
    data
      ..clear()
      ..addEntries(sortedEntries);
    return PhysicalKeyData._(data);
  }

  /// Parses the given JSON data and populates the data structure from it.
  factory PhysicalKeyData.fromJson(Map<String, dynamic> contentMap) {
    final Map<String, PhysicalKeyEntry> data = <String, PhysicalKeyEntry>{};
    for (final MapEntry<String, dynamic> jsonEntry in contentMap.entries) {
      final PhysicalKeyEntry entry = PhysicalKeyEntry.fromJsonMapEntry(jsonEntry.value as Map<String, dynamic>);
      data[entry.name] = entry;
    }
    return PhysicalKeyData._(data);
  }

  PhysicalKeyData._(this._data);

  /// Find an entry from name, or null if not found.
  PhysicalKeyEntry? tryEntryByName(String name) {
    return _data[name];
  }

  /// Find an entry from name.
  ///
  /// Asserts if the name is not found.
  PhysicalKeyEntry entryByName(String name) {
    final PhysicalKeyEntry? entry = tryEntryByName(name);
    assert(entry != null,
        'Unable to find logical entry by name $name.');
    return entry!;
  }

  /// All entries.
  Iterable<PhysicalKeyEntry> get entries => _data.values;

  // Keys mapped from their names.
  final Map<String, PhysicalKeyEntry> _data;

  /// Converts the data structure into a JSON structure that can be parsed by
  /// [PhysicalKeyData.fromJson].
  Map<String, dynamic> toJson() {
    final Map<String, dynamic> outputMap = <String, dynamic>{};
    for (final PhysicalKeyEntry entry in _data.values) {
      outputMap[entry.name] = entry.toJson();
    }
    return outputMap;
  }

  /// Parses entries from Androids Generic.kl scan code data file.
  ///
  /// Lines in this file look like this (without the ///):
  /// key 100   ALT_RIGHT
  /// # key 101 "KEY_LINEFEED"
  /// key 477   F12               FUNCTION
  ///
  /// We parse the commented out lines as well as the non-commented lines, so
  /// that we can get names for all of the available scan codes, not just ones
  /// defined for the generic profile.
  ///
  /// Also, note that some keys (notably MEDIA_EJECT) can be mapped to more than
  /// one scan code, so the mapping can't just be 1:1, it has to be 1:many.
  static Map<String, List<int>> _readAndroidScanCodes(String keyboardLayout, String nameMap) {
    final RegExp keyEntry = RegExp(
      r'#?\s*' // Optional comment mark
      r'key\s+' // Literal "key"
      r'(?<id>[0-9]+)\s*' // ID section
      r'"?(?:KEY_)?(?<name>[0-9A-Z_]+|\(undefined\))"?\s*' // Name section
      r'(?<function>FUNCTION)?' // Optional literal "FUNCTION"
    );
    final Map<String, List<int>> androidNameToScanCodes = <String, List<int>>{};
    for (final RegExpMatch match in keyEntry.allMatches(keyboardLayout)) {
      if (match.namedGroup('function') == 'FUNCTION') {
        // Skip odd duplicate Android FUNCTION keys (F1-F12 are already defined).
        continue;
      }
      final String name = match.namedGroup('name')!;
      if (name == '(undefined)') {
        // Skip undefined scan codes.
        continue;
      }
      androidNameToScanCodes.putIfAbsent(name, () => <int>[])
        .add(int.parse(match.namedGroup('id')!));
    }

    // Cast Android dom map
    final Map<String, List<String>> nameToAndroidNames = (json.decode(nameMap) as Map<String, dynamic>)
      .cast<String, List<dynamic>>()
      .map<String, List<String>>((String key, List<dynamic> value) {
        return MapEntry<String, List<String>>(key, value.cast<String>());
      });

    final Map<String, List<int>> result = nameToAndroidNames.map((String name, List<String> androidNames) {
      final Set<int> scanCodes = <int>{};
      for (final String androidName in androidNames) {
        scanCodes.addAll(androidNameToScanCodes[androidName] ?? <int>[]);
      }
      return MapEntry<String, List<int>>(name, scanCodes.toList()..sort());
    });

    return result;
  }

  /// Parses entries from Chromium's HID code mapping header file.
  ///
  /// Lines in this file look like this (without the ///):
  ///            USB       evdev   XKB     Win     Mac     Code     Enum
  /// DOM_CODE(0x000010, 0x0000, 0x0000, 0x0000, 0xffff, "Hyper", HYPER),
  static Map<String, PhysicalKeyEntry> _readHidEntries(
    String input,
    Map<String, List<int>> nameToAndroidScanCodes,
  ) {
    final Map<int, PhysicalKeyEntry> entries = <int, PhysicalKeyEntry>{};
    final RegExp usbMapRegExp = RegExp(
      r'DOM_CODE\s*\(\s*'
      r'0[xX](?<usb>[a-fA-F0-9]+),\s*'
      r'0[xX](?<evdev>[a-fA-F0-9]+),\s*'
      r'0[xX](?<xkb>[a-fA-F0-9]+),\s*'
      r'0[xX](?<win>[a-fA-F0-9]+),\s*'
      r'0[xX](?<mac>[a-fA-F0-9]+),\s*'
      r'(?:"(?<code>[^\s]+)")?[^")]*?,'
      r'\s*(?<enum>[^\s]+?)\s*'
      r'\)',
      // Multiline is necessary because some definitions spread across
      // multiple lines.
      multiLine: true,
    );
    final RegExp commentRegExp = RegExp(r'//.*$', multiLine: true);
    input = input.replaceAll(commentRegExp, '');
    for (final RegExpMatch match in usbMapRegExp.allMatches(input)) {
      final int usbHidCode = getHex(match.namedGroup('usb')!);
      final int evdevCode = getHex(match.namedGroup('evdev')!);
      final int xKbScanCode = getHex(match.namedGroup('xkb')!);
      final int windowsScanCode = getHex(match.namedGroup('win')!);
      final int macScanCode = getHex(match.namedGroup('mac')!);
      final String? chromiumCode = match.namedGroup('code');
      // The input data has a typo...
      final String enumName = match.namedGroup('enum')!.replaceAll('MINIMIUM', 'MINIMUM');

      final String name = chromiumCode ?? shoutingToUpperCamel(enumName);
      if (name == 'IntlHash' || name == 'None') {
        // Skip key that is not actually generated by any keyboard.
        continue;
      }
      final PhysicalKeyEntry newEntry = PhysicalKeyEntry(
        usbHidCode: usbHidCode,
        androidScanCodes: nameToAndroidScanCodes[name] ?? <int>[],
        evdevCode: evdevCode == 0 ? null : evdevCode,
        xKbScanCode: xKbScanCode == 0 ? null : xKbScanCode,
        windowsScanCode: windowsScanCode == 0 ? null : windowsScanCode,
        macOSScanCode: macScanCode == 0xffff ? null : macScanCode,
        iOSScanCode: (usbHidCode & 0x070000) == 0x070000 ? (usbHidCode ^ 0x070000) : null,
        name: name,
        chromiumCode: chromiumCode,
      );
      // Remove duplicates: last one wins, so that supplemental codes
      // override.
      if (entries.containsKey(newEntry.usbHidCode)) {
        // This is expected for Fn. Warn for other keys.
        if (newEntry.name != 'Fn') {
          print('Duplicate usbHidCode ${newEntry.usbHidCode} of key ${newEntry.name} '
            'conflicts with existing ${entries[newEntry.usbHidCode]!.name}. Keeping the new one.');
        }
      }
      entries[newEntry.usbHidCode] = newEntry;
    }
    return entries.map((int code, PhysicalKeyEntry entry) =>
        MapEntry<String, PhysicalKeyEntry>(entry.name, entry));
  }
}

/// A single entry in the key data structure.
///
/// Can be read from JSON with the [PhysicalKeyEntry.fromJsonMapEntry] constructor, or
/// written with the [toJson] method.
class PhysicalKeyEntry {
  /// Creates a single key entry from available data.
  ///
  /// The [usbHidCode] and [chromiumName] parameters must not be null.
  PhysicalKeyEntry({
    required this.usbHidCode,
    required this.name,
    required this.androidScanCodes,
    required this.evdevCode,
    required this.xKbScanCode,
    required this.windowsScanCode,
    required this.macOSScanCode,
    required this.iOSScanCode,
    required this.chromiumCode,
  });

  /// Populates the key from a JSON map.
  factory PhysicalKeyEntry.fromJsonMapEntry(Map<String, dynamic> map) {
    final Map<String, dynamic> names = map['names'] as Map<String, dynamic>;
    final Map<String, dynamic> scanCodes = map['scanCodes'] as Map<String, dynamic>;
    return PhysicalKeyEntry(
      name: names['name'] as String,
      chromiumCode: names['chromium'] as String?,
      usbHidCode: scanCodes['usb'] as int,
      androidScanCodes: (scanCodes['android'] as List<dynamic>?)?.cast<int>() ?? <int>[],
      evdevCode: scanCodes['linux'] as int?,
      xKbScanCode: scanCodes['xkb'] as int?,
      windowsScanCode: scanCodes['windows'] as int?,
      macOSScanCode: scanCodes['macos'] as int?,
      iOSScanCode: scanCodes['ios'] as int?,
    );
  }

  /// The USB HID code of the key
  final int usbHidCode;

  /// The Evdev scan code of the key, from Chromium's header file.
  final int? evdevCode;
  /// The XKb scan code of the key from Chromium's header file.
  final int? xKbScanCode;
  /// The Windows scan code of the key from Chromium's header file.
  final int? windowsScanCode;
  /// The macOS scan code of the key from Chromium's header file.
  final int? macOSScanCode;
  /// The iOS scan code of the key from UIKey's documentation (USB Hid table)
  final int? iOSScanCode;
  /// The list of Android scan codes matching this key, created by looking up
  /// the Android name in the Chromium data, and substituting the Android scan
  /// code value.
  final List<int> androidScanCodes;
  /// The name of the key, mostly derived from the DomKey name in Chromium,
  /// but where there was no DomKey representation, derived from the Chromium
  /// symbol name.
  final String name;
  /// The Chromium event code for the key.
  final String? chromiumCode;

  /// Creates a JSON map from the key data.
  Map<String, dynamic> toJson() {
    return removeEmptyValues(<String, dynamic>{
      'names': <String, dynamic>{
        'name': name,
        'chromium': chromiumCode,
      },
      'scanCodes': <String, dynamic>{
        'android': androidScanCodes,
        'usb': usbHidCode,
        'linux': evdevCode,
        'xkb': xKbScanCode,
        'windows': windowsScanCode,
        'macos': macOSScanCode,
        'ios': iOSScanCode,
      },
    });
  }

  static String getCommentName(String constantName) {
    String upperCamel = lowerCamelToUpperCamel(constantName);
    upperCamel = upperCamel.replaceAllMapped(
      RegExp(r'(Digit|Numpad|Lang|Button|Left|Right)([0-9]+)'),
      (Match match) => '${match.group(1)} ${match.group(2)}',
    );
    return upperCamel.replaceAllMapped(RegExp(r'([A-Z])'), (Match match) => ' ${match.group(1)}').trim();
  }

  /// Gets the name of the key suitable for placing in comments.
  ///
  /// Takes the [constantName] and converts it from lower camel case to capitalized
  /// separate words (e.g. "wakeUp" converts to "Wake Up").
  String get commentName => getCommentName(constantName);

  /// Gets the named used for the key constant in the definitions in
  /// keyboard_key.dart.
  ///
  /// If set by the constructor, returns the name set, but otherwise constructs
  /// the name from the various different names available, making sure that the
  /// name isn't a Dart reserved word (if it is, then it adds the word "Key" to
  /// the end of the name).
  late final String constantName = (() {
    String? result;
    if (name.isEmpty) {
      // If it doesn't have a DomKey name then use the Chromium symbol name.
      result = chromiumCode;
    } else {
      result = upperCamelToLowerCamel(name);
    }
    result ??= 'Key${toHex(usbHidCode)}';
    if (kDartReservedWords.contains(result)) {
      return '${result}Key';
    }
    return result;
  })();

  @override
  String toString() {
    return """'$constantName': (name: "$name", usbHidCode: ${toHex(usbHidCode)}, """
        'linuxScanCode: ${toHex(evdevCode)}, xKbScanCode: ${toHex(xKbScanCode)}, '
        'windowsKeyCode: ${toHex(windowsScanCode)}, macOSScanCode: ${toHex(macOSScanCode)}, '
        'windowsScanCode: ${toHex(windowsScanCode)}, chromiumSymbolName: $chromiumCode '
        'iOSScanCode: ${toHex(iOSScanCode)})';
  }

  static int compareByUsbHidCode(PhysicalKeyEntry a, PhysicalKeyEntry b) =>
      a.usbHidCode.compareTo(b.usbHidCode);
}
