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


/// Generates the key mapping for Android, based on the information in the key
/// data structure given to it.
class AndroidCodeGenerator extends PlatformCodeGenerator {
  AndroidCodeGenerator(super.physicalData, super.logicalData);

  /// This generates the map of Android key codes to logical keys.
  String get _androidKeyCodeMap {
    final StringBuffer androidKeyCodeMap = StringBuffer();
    for (final LogicalKeyEntry entry in logicalData.entries) {
      for (final int code in entry.androidValues) {
        androidKeyCodeMap.writeln('          put(${toHex(code, digits: 10)}L, ${toHex(entry.value, digits: 10)}L); // ${entry.constantName}');
      }
    }
    return androidKeyCodeMap.toString().trimRight();
  }

  /// This generates the map of Android scan codes to physical keys.
  String get _androidScanCodeMap {
    final StringBuffer androidScanCodeMap = StringBuffer();
    for (final PhysicalKeyEntry entry in keyData.entries) {
      if (entry.androidScanCodes != null) {
        for (final int code in entry.androidScanCodes.cast<int>()) {
          androidScanCodeMap.writeln('          put(${toHex(code, digits: 10)}L, ${toHex(entry.usbHidCode, digits: 10)}L); // ${entry.constantName}');
        }
      }
    }
    return androidScanCodeMap.toString().trimRight();
  }

  String get _pressingGoals {
    final OutputLines<int> lines = OutputLines<int>('Android pressing goals');
    const Map<String, List<String>> goalsSource = <String, List<String>>{
      'SHIFT': <String>['ShiftLeft', 'ShiftRight'],
      'CTRL': <String>['ControlLeft', 'ControlRight'],
      'ALT': <String>['AltLeft', 'AltRight'],
    };
    goalsSource.forEach((String flagName, List<String> keys) {
      int? lineId;
      final List<String> keysString = keys.map((String keyName) {
        final PhysicalKeyEntry physicalKey = keyData.entryByName(keyName);
        final LogicalKeyEntry logicalKey = logicalData.entryByName(keyName);
        lineId ??= physicalKey.usbHidCode;
        return '              new KeyPair(${toHex(physicalKey.usbHidCode)}L, '
          '${toHex(logicalKey.value, digits: 10)}L), // ${physicalKey.name}';
      }).toList();
      lines.add(lineId!,
          '        new PressingGoal(\n'
          '            KeyEvent.META_${flagName}_ON,\n'
          '            new KeyPair[] {\n'
          '${keysString.join('\n')}\n'
          '            }),');
    });
    return lines.sortedJoin().trimRight();
  }

  String get _togglingGoals {
    final OutputLines<int> lines = OutputLines<int>('Android toggling goals');
    const Map<String, String> goalsSource = <String, String>{
      'CAPS_LOCK': 'CapsLock',
    };
    goalsSource.forEach((String flagName, String keyName) {
      final PhysicalKeyEntry physicalKey = keyData.entryByName(keyName);
      final LogicalKeyEntry logicalKey = logicalData.entryByName(keyName);
      lines.add(physicalKey.usbHidCode,
          '      new TogglingGoal(KeyEvent.META_${flagName}_ON, '
          '${toHex(physicalKey.usbHidCode)}L, '
          '${toHex(logicalKey.value, digits: 10)}L),');
    });
    return lines.sortedJoin().trimRight();
  }

  /// This generates the mask values for the part of a key code that defines its plane.
  String get _maskConstants {
    final StringBuffer buffer = StringBuffer();
    const List<MaskConstant> maskConstants = <MaskConstant>[
      kValueMask,
      kUnicodePlane,
      kAndroidPlane,
    ];
    for (final MaskConstant constant in maskConstants) {
      buffer.writeln('  public static final long k${constant.upperCamelName} = ${toHex(constant.value, digits: 11)}L;');
    }
    return buffer.toString().trimRight();
  }

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

  @override
  String outputPath(String platform) => path.join(PlatformCodeGenerator.engineRoot, 'shell', 'platform',
      path.join('android', 'io', 'flutter', 'embedding', 'android', 'KeyboardMap.java'));

  @override
  Map<String, String> mappings() {
    return <String, String>{
      'ANDROID_SCAN_CODE_MAP': _androidScanCodeMap,
      'ANDROID_KEY_CODE_MAP': _androidKeyCodeMap,
      'PRESSING_GOALS': _pressingGoals,
      'TOGGLING_GOALS': _togglingGoals,
      'MASK_CONSTANTS': _maskConstants,
    };
  }
}
