// 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 'dart:io' hide Platform;

import 'package:args/args.dart';
import 'package:gen_keycodes/android_code_gen.dart';
import 'package:gen_keycodes/base_code_gen.dart';
import 'package:gen_keycodes/gtk_code_gen.dart';
import 'package:gen_keycodes/ios_code_gen.dart';
import 'package:gen_keycodes/keyboard_keys_code_gen.dart';
import 'package:gen_keycodes/keyboard_maps_code_gen.dart';
import 'package:gen_keycodes/logical_key_data.dart';
import 'package:gen_keycodes/macos_code_gen.dart';
import 'package:gen_keycodes/physical_key_data.dart';
import 'package:gen_keycodes/testing_key_codes_cc_gen.dart';
import 'package:gen_keycodes/testing_key_codes_java_gen.dart';
import 'package:gen_keycodes/utils.dart';
import 'package:gen_keycodes/web_code_gen.dart';
import 'package:gen_keycodes/windows_code_gen.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;

/// Get contents of the file that contains the physical key mapping in Chromium
/// source.
Future<String> getChromiumCodes() async {
  final Uri keyCodesUri = Uri.parse('https://chromium.googlesource.com/codesearch/chromium/src/+/refs/heads/main/ui/events/keycodes/dom/dom_code_data.inc?format=TEXT');
  return utf8.decode(base64.decode(await http.read(keyCodesUri)));
}

/// Get contents of the file that contains the logical key mapping in Chromium
/// source.
Future<String> getChromiumKeys() async {
  final Uri keyCodesUri = Uri.parse('https://chromium.googlesource.com/codesearch/chromium/src/+/refs/heads/main/ui/events/keycodes/dom/dom_key_data.inc?format=TEXT');
  return utf8.decode(base64.decode(await http.read(keyCodesUri)));
}

/// Get contents of the file that contains the key codes in Android source.
Future<String> getAndroidKeyCodes() async {
  final Uri keyCodesUri = Uri.parse('https://android.googlesource.com/platform/frameworks/native/+/main/include/android/keycodes.h?format=TEXT');
  return utf8.decode(base64.decode(await http.read(keyCodesUri)));
}

Future<String> getWindowsKeyCodes() async {
  final Uri keyCodesUri = Uri.parse('https://raw.githubusercontent.com/tpn/winsdk-10/master/Include/10.0.10240.0/um/WinUser.h');
  return http.read(keyCodesUri);
}

/// Get contents of the file that contains the scan codes in Android source.
/// Yes, this is just the generic keyboard layout file for base Android distro
/// This is because there isn't any facility in Android to get the keyboard
/// layout, so we're using this to match scan codes with symbol names for most
/// common keyboards. Other than some special keyboards and game pads, this
/// should be OK.
Future<String> getAndroidScanCodes() async {
  final Uri scanCodesUri = Uri.parse('https://android.googlesource.com/platform/frameworks/base/+/main/data/keyboards/Generic.kl?format=TEXT');
  return utf8.decode(base64.decode(await http.read(scanCodesUri)));
}

Future<String> getGlfwKeyCodes() async {
  final Uri keyCodesUri = Uri.parse('https://raw.githubusercontent.com/glfw/glfw/master/include/GLFW/glfw3.h');
  return http.read(keyCodesUri);
}

Future<String> getGtkKeyCodes() async {
  final Uri keyCodesUri = Uri.parse('https://gitlab.gnome.org/GNOME/gtk/-/raw/gtk-3-24/gdk/gdkkeysyms.h');
  return http.read(keyCodesUri);
}

String readDataFile(String fileName) {
  return File(path.join(dataRoot, fileName)).readAsStringSync();
}

bool _assertsEnabled() {
  bool enabledAsserts = false;
  assert(() {
    enabledAsserts = true;
    return true;
  }());
  return enabledAsserts;
}

Future<void> generate(String name, String outDir, BaseCodeGenerator generator) {
  final File codeFile = File(outDir);
  if (!codeFile.existsSync()) {
    codeFile.createSync(recursive: true);
  }
  print('Writing ${name.padRight(15)}${codeFile.absolute}');
  return codeFile.writeAsString(generator.generate());
}

Future<void> main(List<String> rawArguments) async {
  if (!_assertsEnabled()) {
    print('The gen_keycodes script must be run with --enable-asserts.');
    return;
  }
  final ArgParser argParser = ArgParser();
  argParser.addOption(
    'engine-root',
    defaultsTo: path.join(flutterRoot.path, '..', 'engine', 'src', 'flutter'),
    help: 'The path to the root of the flutter/engine repository. This is used '
        'to place the generated engine mapping files. If --engine-root is not '
        r'specified, it will default to $flutterRoot/../engine/src/flutter, '
        'assuming the engine gclient folder is placed at the same folder as '
        'the flutter/flutter repository.',
  );
  argParser.addOption(
    'physical-data',
    defaultsTo: path.join(dataRoot, 'physical_key_data.g.json'),
    help: 'The path to where the physical key data file should be written when '
        'collected, and read from when generating output code. If --physical-data is '
        'not specified, the output will be written to/read from the current '
        "directory. If the output directory doesn't exist, it, and the path to "
        'it, will be created.',
  );
  argParser.addOption(
    'logical-data',
    defaultsTo: path.join(dataRoot, 'logical_key_data.g.json'),
    help: 'The path to where the logical key data file should be written when '
        'collected, and read from when generating output code. If --logical-data is '
        'not specified, the output will be written to/read from the current '
        "directory. If the output directory doesn't exist, it, and the path to "
        'it, will be created.',
  );
  argParser.addOption(
    'code',
    defaultsTo: path.join(flutterRoot.path, 'packages', 'flutter', 'lib', 'src', 'services', 'keyboard_key.g.dart'),
    help: 'The path to where the output "keyboard_key.g.dart" file should be '
        'written. If --code is not specified, the output will be written to the '
        'correct directory in the flutter tree. If the output directory does not '
        'exist, it, and the path to it, will be created.',
  );
  argParser.addOption(
    'maps',
    defaultsTo: path.join(flutterRoot.path, 'packages', 'flutter', 'lib', 'src', 'services', 'keyboard_maps.g.dart'),
    help: 'The path to where the output "keyboard_maps.g.dart" file should be '
      'written. If --maps is not specified, the output will be written to the '
      'correct directory in the flutter tree. If the output directory does not '
      'exist, it, and the path to it, will be created.',
  );
  argParser.addFlag(
    'collect',
    negatable: false,
    help: 'If this flag is set, then collect and parse header files from '
        'Chromium and Android instead of reading pre-parsed data from '
        '"physical_key_data.g.json" and "logical_key_data.g.json", and then '
        'update these files with the fresh data.',
  );
  argParser.addFlag(
    'help',
    negatable: false,
    help: 'Print help for this command.',
  );

  final ArgResults parsedArguments = argParser.parse(rawArguments);

  if (parsedArguments['help'] as bool) {
    print(argParser.usage);
    exit(0);
  }

  PlatformCodeGenerator.engineRoot = parsedArguments['engine-root'] as String;

  PhysicalKeyData physicalData;
  LogicalKeyData logicalData;
  if (parsedArguments['collect'] as bool) {
    // Physical
    final String baseHidCodes = await getChromiumCodes();
    final String supplementalHidCodes = readDataFile('supplemental_hid_codes.inc');
    final String androidScanCodes = await getAndroidScanCodes();
    final String androidToDomKey = readDataFile('android_key_name_to_name.json');
    physicalData = PhysicalKeyData(
      <String>[baseHidCodes, supplementalHidCodes].join('\n'),
      androidScanCodes,
      androidToDomKey,
    );

    // Logical
    final String gtkKeyCodes = await getGtkKeyCodes();
    final String webLogicalKeys = await getChromiumKeys();
    final String supplementalKeyData = readDataFile('supplemental_key_data.inc');
    final String gtkToDomKey = readDataFile('gtk_logical_name_mapping.json');
    final String windowsKeyCodes = await getWindowsKeyCodes();
    final String windowsToDomKey = readDataFile('windows_logical_to_window_vk.json');
    final String macosLogicalToPhysical = readDataFile('macos_logical_to_physical.json');
    final String iosLogicalToPhysical = readDataFile('ios_logical_to_physical.json');
    final String androidKeyCodes = await getAndroidKeyCodes();
    final String glfwKeyCodes = await getGlfwKeyCodes();
    final String glfwToDomKey = readDataFile('glfw_key_name_to_name.json');

    logicalData = LogicalKeyData(
      <String>[webLogicalKeys, supplementalKeyData].join('\n'),
      gtkKeyCodes,
      gtkToDomKey,
      windowsKeyCodes,
      windowsToDomKey,
      androidKeyCodes,
      androidToDomKey,
      macosLogicalToPhysical,
      iosLogicalToPhysical,
      glfwKeyCodes,
      glfwToDomKey,
      physicalData,
    );

    // Write data files
    const JsonEncoder encoder = JsonEncoder.withIndent('  ');
    final String physicalJson = encoder.convert(physicalData.toJson());
    File(parsedArguments['physical-data'] as String).writeAsStringSync('$physicalJson\n');
    final String logicalJson = encoder.convert(logicalData.toJson());
    File(parsedArguments['logical-data'] as String).writeAsStringSync('$logicalJson\n');
  } else {
    physicalData = PhysicalKeyData.fromJson(json.decode(await File(parsedArguments['physical-data'] as String).readAsString()) as Map<String, dynamic>);
    logicalData = LogicalKeyData.fromJson(json.decode(await File(parsedArguments['logical-data'] as String).readAsString()) as Map<String, dynamic>);
  }

  final Map<String, bool> layoutGoals = parseMapOfBool(readDataFile('layout_goals.json'));

  await generate('key codes',
      parsedArguments['code'] as String,
      KeyboardKeysCodeGenerator(physicalData, logicalData));
  await generate('key maps',
      parsedArguments['maps'] as String,
      KeyboardMapsCodeGenerator(physicalData, logicalData));
  await generate('engine utils',
      path.join(PlatformCodeGenerator.engineRoot,
          'shell', 'platform', 'embedder', 'test_utils', 'key_codes.g.h'),
      KeyCodesCcGenerator(physicalData, logicalData));
  await generate('android utils',
      path.join(PlatformCodeGenerator.engineRoot, 'shell', 'platform',
          path.join('android', 'test', 'io', 'flutter', 'util', 'KeyCodes.java')),
      KeyCodesJavaGenerator(physicalData, logicalData));

  final Map<String, PlatformCodeGenerator> platforms = <String, PlatformCodeGenerator>{
    'android': AndroidCodeGenerator(
      physicalData,
      logicalData,
    ),
    'macos': MacOSCodeGenerator(
      physicalData,
      logicalData,
      layoutGoals,
    ),
    'ios': IOSCodeGenerator(
      physicalData,
      logicalData,
    ),
    'windows': WindowsCodeGenerator(
      physicalData,
      logicalData,
      readDataFile('windows_scancode_logical_map.json')
    ),
    'linux': GtkCodeGenerator(
      physicalData,
      logicalData,
      readDataFile('gtk_modifier_bit_mapping.json'),
      readDataFile('gtk_lock_bit_mapping.json'),
      layoutGoals,
    ),
    'web': WebCodeGenerator(
      physicalData,
      logicalData,
      readDataFile('web_logical_location_mapping.json'),
    ),
  };
  await Future.wait(platforms.entries.map((MapEntry<String, PlatformCodeGenerator> entry) {
    final String platform = entry.key;
    final PlatformCodeGenerator codeGenerator = entry.value;
    return generate('$platform map',
        codeGenerator.outputPath(platform),
        codeGenerator);
  }));
}
