// 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 'package:path/path.dart' as path;

import 'base_code_gen.dart';
import 'constants.dart';
import 'logical_key_data.dart';
import 'physical_key_data.dart';
import 'utils.dart';

/// Given an [input] string, wraps the text at 80 characters and prepends each
/// line with the [prefix] string. Use for generated comments.
String _wrapString(String input) {
  return wrapString(input, prefix: '  /// ');
}

final List<MaskConstant> _maskConstants = <MaskConstant>[
  kValueMask,
  kPlaneMask,
  kUnicodePlane,
  kUnprintablePlane,
  kFlutterPlane,
  kStartOfPlatformPlanes,
  kAndroidPlane,
  kFuchsiaPlane,
  kIosPlane,
  kMacosPlane,
  kGtkPlane,
  kWindowsPlane,
  kWebPlane,
  kGlfwPlane,
];

class SynonymKeyInfo {
  SynonymKeyInfo(this.keys, this.name);

  final List<LogicalKeyEntry> keys;
  final String name;

  // Use the first item in the synonyms as a template for the ID to use.
  // It won't end up being the same value because it'll be in the pseudo-key
  // plane.
  LogicalKeyEntry get primaryKey => keys[0];
  String get constantName => upperCamelToLowerCamel(name);
}

/// Generates the keyboard_key.dart based on the information in the key data
/// structure given to it.
class KeyboardKeysCodeGenerator extends BaseCodeGenerator {
  KeyboardKeysCodeGenerator(PhysicalKeyData keyData, LogicalKeyData logicalData) : super(keyData, logicalData);

  /// Gets the generated definitions of PhysicalKeyboardKeys.
  String get _physicalDefinitions {
    final OutputLines<int> lines = OutputLines<int>('Physical Key Definition');
    for (final PhysicalKeyEntry entry in keyData.entries) {
      final String firstComment = _wrapString('Represents the location of the '
        '"${entry.commentName}" key on a generalized keyboard.');
      final String otherComments = _wrapString('See the function '
        '[RawKeyEvent.physicalKey] for more information.');
      lines.add(entry.usbHidCode, '''
$firstComment  ///
$otherComments  static const PhysicalKeyboardKey ${entry.constantName} = PhysicalKeyboardKey(${toHex(entry.usbHidCode, digits: 8)});
''');
    }
    return lines.sortedJoin().trimRight();
  }

  String get _physicalDebugNames {
    final OutputLines<int> lines = OutputLines<int>('Physical debug names');
    for (final PhysicalKeyEntry entry in keyData.entries) {
      lines.add(entry.usbHidCode, '''
      ${toHex(entry.usbHidCode, digits: 8)}: '${entry.commentName}',''');
    }
    return lines.sortedJoin().trimRight();
  }

  /// Gets the generated definitions of LogicalKeyboardKeys.
  String get _logicalDefinitions {
    final OutputLines<int> lines = OutputLines<int>('Logical debug names');
    void printKey(int flutterId, String constantName, String commentName, {String? otherComments}) {
      final String firstComment = _wrapString('Represents the logical "$commentName" key on the keyboard.');
      otherComments ??= _wrapString('See the function [RawKeyEvent.logicalKey] for more information.');
      lines.add(flutterId, '''
$firstComment  ///
$otherComments  static const LogicalKeyboardKey $constantName = LogicalKeyboardKey(${toHex(flutterId, digits: 11)});
''');
    }

    for (final LogicalKeyEntry entry in logicalData.entries) {
      printKey(
        entry.value,
        entry.constantName,
        entry.commentName,
        otherComments: _otherComments(entry.name),
      );
    }
    return lines.sortedJoin().trimRight();
  }

  String? _otherComments(String name) {
    if (synonyms.containsKey(name)) {
      final Set<String> unionNames = synonyms[name]!.keys.map(
        (LogicalKeyEntry entry) => entry.constantName).toSet();
      return _wrapString('This key represents the union of the keys '
              '$unionNames when comparing keys. This key will never be generated '
              'directly, its main use is in defining key maps.');
    }
    return null;
  }

  String get _logicalSynonyms {
    final StringBuffer result = StringBuffer();
    for (final SynonymKeyInfo synonymInfo in synonyms.values) {
      for (final LogicalKeyEntry key in synonymInfo.keys) {
        final LogicalKeyEntry synonnym = logicalData.entryByName(synonymInfo.name);
        result.writeln('    ${key.constantName}: ${synonnym.constantName},');
      }
    }
    return result.toString();
  }

  String get _logicalKeyLabels {
    final OutputLines<int> lines = OutputLines<int>('Logical key labels');
    for (final LogicalKeyEntry entry in logicalData.entries) {
      lines.add(entry.value, '''
    ${toHex(entry.value, digits: 11)}: '${entry.commentName}',''');
    }
    return lines.sortedJoin().trimRight();
  }

  /// This generates the map of USB HID codes to physical keys.
  String get _predefinedHidCodeMap {
    final OutputLines<int> lines = OutputLines<int>('Physical key map');
    for (final PhysicalKeyEntry entry in keyData.entries) {
      lines.add(entry.usbHidCode, '    ${toHex(entry.usbHidCode)}: ${entry.constantName},');
    }
    return lines.sortedJoin().trimRight();
  }

  /// This generates the map of Flutter key codes to logical keys.
  String get _predefinedKeyCodeMap {
    final OutputLines<int> lines = OutputLines<int>('Logical key map');
    for (final LogicalKeyEntry entry in logicalData.entries) {
      lines.add(entry.value, '    ${toHex(entry.value, digits: 11)}: ${entry.constantName},');
    }
    return lines.sortedJoin().trimRight();
  }

  String get _maskConstantVariables {
    final OutputLines<int> lines = OutputLines<int>('Mask constants', checkDuplicate: false);
    for (final MaskConstant constant in _maskConstants) {
      lines.add(constant.value, '''
${_wrapString(constant.description)}  ///
  /// This is used by platform-specific code to generate Flutter key codes.
  static const int ${constant.lowerCamelName} = ${toHex(constant.value, digits: 11)};
''');
    }
    return lines.join().trimRight();
  }

  @override
  String get templatePath => path.join(dataRoot, 'keyboard_key.tmpl');

  @override
  Map<String, String> mappings() {
    return <String, String>{
      'LOGICAL_KEY_MAP': _predefinedKeyCodeMap,
      'LOGICAL_KEY_DEFINITIONS': _logicalDefinitions,
      'LOGICAL_KEY_SYNONYMS': _logicalSynonyms,
      'LOGICAL_KEY_KEY_LABELS': _logicalKeyLabels,
      'PHYSICAL_KEY_MAP': _predefinedHidCodeMap,
      'PHYSICAL_KEY_DEFINITIONS': _physicalDefinitions,
      'PHYSICAL_KEY_DEBUG_NAMES': _physicalDebugNames,
      'MASK_CONSTANTS': _maskConstantVariables,
    };
  }

  late final Map<String, SynonymKeyInfo> synonyms = Map<String, SynonymKeyInfo>.fromEntries(
    LogicalKeyData.synonyms.entries.map((MapEntry<String, List<String>> synonymDefinition) {
      final List<LogicalKeyEntry> entries = synonymDefinition.value.map(
        (String name) => logicalData.entryByName(name)).toList();
      return MapEntry<String, SynonymKeyInfo>(
        synonymDefinition.key,
        SynonymKeyInfo(
          entries,
          synonymDefinition.key,
        ),
      );
    }),
  );
}
