// 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 'package:gen_keycodes/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,
    String glfwHeaderFile,
    String glfwNameMap,
  ) {
    final Map<String, List<int>> nameToAndroidScanCodes = _readAndroidScanCodes(androidKeyboardLayout, androidNameMap);
    final Map<String, List<int>> nameToGlfwKeyCodes = _readGlfwKeyCodes(glfwHeaderFile, glfwNameMap);
    final Map<String, PhysicalKeyEntry> data = _readHidEntries(
      chromiumHidCodes,
      nameToAndroidScanCodes,
      nameToGlfwKeyCodes,
    );
    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 GLFW's keycodes.h key code data file.
  ///
  /// Lines in this file look like this (without the ///):
  ///  /** Space key. */
  ///  #define GLFW_KEY_SPACE              32,
  ///  #define GLFW_KEY_LAST               GLFW_KEY_MENU

  static Map<String, List<int>> _readGlfwKeyCodes(String headerFile, String nameMap) {
    // Only get the KEY definitions, ignore the rest (mouse, joystick, etc).
    final RegExp definedCodes = RegExp(
      r'define\s+'
      r'GLFW_KEY_(?<name>[A-Z0-9_]+)\s+'
      r'(?<value>[A-Z0-9_]+),?',
    );
    final Map<String, dynamic> replaced = <String, dynamic>{};
    for (final RegExpMatch match in definedCodes.allMatches(headerFile)) {
      final String name = match.namedGroup('name')!;
      final String value = match.namedGroup('value')!;
      replaced[name] = int.tryParse(value) ?? value.replaceAll('GLFW_KEY_', '');
    }
    final Map<String, int> glfwNameToKeyCode = <String, int>{};
    replaced.forEach((String key, dynamic value) {
      // Some definition values point to other definitions (e.g #define GLFW_KEY_LAST GLFW_KEY_MENU).
      if (value is String) {
        glfwNameToKeyCode[key] = replaced[value] as int;
      } else {
        glfwNameToKeyCode[key] = value as int;
      }
    });

    final Map<String, List<String>> nameToGlfwNames = (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 = nameToGlfwNames.map((String name, List<String> glfwNames) {
      final Set<int> keyCodes = <int>{};
      for (final String glfwName in glfwNames) {
        if (glfwNameToKeyCode[glfwName] != null)
          keyCodes.add(glfwNameToKeyCode[glfwName]!);
      }
      return MapEntry<String, List<int>>(name, keyCodes.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,
    Map<String, List<int>> nameToGlfwKeyCodes,
  ) {
    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 linuxScanCode = 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') {
        // Skip key that is not actually generated by any keyboard.
        continue;
      }
      final PhysicalKeyEntry newEntry = PhysicalKeyEntry(
        usbHidCode: usbHidCode,
        androidScanCodes: nameToAndroidScanCodes[name] ?? <int>[],
        glfwKeyCodes: nameToGlfwKeyCodes[name] ?? <int>[],
        linuxScanCode: linuxScanCode == 0 ? null : linuxScanCode,
        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.linuxScanCode,
    required this.xKbScanCode,
    required this.windowsScanCode,
    required this.macOSScanCode,
    required this.iOSScanCode,
    required this.chromiumCode,
    required this.glfwKeyCodes,
  });

  /// 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>;
    final Map<String, dynamic>? keyCodes = map['keyCodes'] 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>[],
      linuxScanCode: scanCodes['linux'] as int?,
      xKbScanCode: scanCodes['xkb'] as int?,
      windowsScanCode: scanCodes['windows'] as int?,
      macOSScanCode: scanCodes['macos'] as int?,
      iOSScanCode: scanCodes['ios'] as int?,
      glfwKeyCodes: (keyCodes?['glfw'] as List<dynamic>?)?.cast<int>() ?? <int>[],
    );
  }

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

  /// The Linux scan code of the key, from Chromium's header file.
  final int? linuxScanCode;
  /// 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 list of GLFW key codes matching this key, created by looking up the
  /// Linux name in the Chromium data, and substituting the GLFW key code
  /// value.
  final List<int> glfwKeyCodes;
  /// 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': linuxScanCode,
        'xkb': xKbScanCode,
        'windows': windowsScanCode,
        'macos': macOSScanCode,
        'ios': iOSScanCode,
      },
      'keyCodes': <String, List<int>>{
        'glfw': glfwKeyCodes,
      },
    });
  }

  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(linuxScanCode)}, 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);
}
