// 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.

// This program generates getMaterialTranslation(), getCupertinoTranslation(),
// and getWidgetsTranslation() functions that look up the translations provided by
// the arb files. The returned value is a generated instance of a
// GlobalMaterialLocalizations, GlobalCupertinoLocalizations, or
// GlobalWidgetsLocalizations object that corresponds to a single locale.
//
// The *.arb files are in packages/flutter_localizations/lib/src/l10n.
//
// The arb (JSON) format files must contain a single map indexed by locale.
// Each map value is itself a map with resource identifier keys and localized
// resource string values.
//
// The arb filenames are expected to have the form "material_(\w+)\.arb" or
// "cupertino_(\w+)\.arb" where the group following "_" identifies the language
// code and the country code, e.g. "material_en.arb" or "material_en_GB.arb".
// In most cases both codes are just two characters.
//
// This app is typically run by hand when a module's .arb files have been
// updated.
//
// ## Usage
//
// Run this program from the root of the git repository.
//
// The following outputs the generated Dart code to the console as a dry run:
//
// ```
// dart dev/tools/localization/bin/gen_localizations.dart
// ```
//
// If you have removed localizations from the canonical localizations, then
// add the '--remove-undefined' flag to also remove them from the other files.
//
// ```
// dart dev/tools/localization/bin/gen_localizations.dart --remove-undefined
// ```
//
// If the data looks good, use the `-w` or `--overwrite` option to overwrite the
// generated_material_localizations.dart, generated_cupertino_localizations.dart,
// and generated_widgets_localizations.dart files in packages/flutter_localizations/lib/src/l10n/:
//
// ```
// dart dev/tools/localization/bin/gen_localizations.dart --overwrite
// ```

import 'dart:io';

import 'package:path/path.dart' as path;

import '../gen_cupertino_localizations.dart';
import '../gen_material_localizations.dart';
import '../gen_widgets_localizations.dart';
import '../localizations_utils.dart';
import '../localizations_validator.dart';
import 'encode_kn_arb_files.dart';

/// This is the core of this script; it generates the code used for translations.
String generateArbBasedLocalizationSubclasses({
  required Map<LocaleInfo, Map<String, String>> localeToResources,
  required Map<LocaleInfo, Map<String, dynamic>> localeToResourceAttributes,
  required String generatedClassPrefix,
  required String baseClass,
  required HeaderGenerator generateHeader,
  required ConstructorGenerator generateConstructor,
  ConstructorGenerator? generateConstructorForCountrySubClass,
  required String factoryName,
  required String factoryDeclaration,
  required bool callsFactoryWithConst,
  required String factoryArguments,
  required String supportedLanguagesConstant,
  required String supportedLanguagesDocMacro,
  String? deprecatedReplacementPackage,
  Set<String>? generatedClassNames,
}) {
  assert(generatedClassPrefix.isNotEmpty);
  assert(baseClass.isNotEmpty);
  assert(factoryName.isNotEmpty);
  assert(factoryDeclaration.isNotEmpty);
  assert(factoryArguments.isNotEmpty);
  assert(supportedLanguagesConstant.isNotEmpty);
  assert(supportedLanguagesDocMacro.isNotEmpty);
  generateConstructorForCountrySubClass ??= generateConstructor;
  final output = StringBuffer();
  output.writeln(
    generateHeader('dart dev/tools/localization/bin/gen_localizations.dart --overwrite'),
  );

  final supportedLocales = StringBuffer();

  final languageToLocales = <String, List<LocaleInfo>>{};
  final languageToScriptCodes = <String, Set<String>>{};
  // Used to calculate if there are any corresponding countries for a given language and script.
  final languageAndScriptToCountryCodes = <LocaleInfo, Set<String>>{};
  final allResourceIdentifiers = <String>{};
  for (final LocaleInfo locale in localeToResources.keys.toList()..sort()) {
    if (locale.scriptCode != null) {
      languageToScriptCodes[locale.languageCode] ??= <String>{};
      languageToScriptCodes[locale.languageCode]!.add(locale.scriptCode!);
    }
    if (locale.countryCode != null && locale.scriptCode != null) {
      final key = LocaleInfo.fromString('${locale.languageCode}_${locale.scriptCode}');
      languageAndScriptToCountryCodes[key] ??= <String>{};
      languageAndScriptToCountryCodes[key]!.add(locale.countryCode!);
    }
    languageToLocales[locale.languageCode] ??= <LocaleInfo>[];
    languageToLocales[locale.languageCode]!.add(locale);
    allResourceIdentifiers.addAll(localeToResources[locale]!.keys.toList()..sort());
  }

  // We generate one class per supported language (e.g.
  // `MaterialLocalizationEn`). These implement everything that is needed by the
  // superclass (e.g. GlobalMaterialLocalizations).

  // We also generate one subclass for each locale with a script code (e.g.
  // `MaterialLocalizationZhHant`). Their superclasses are the aforementioned
  // language classes for the same locale but without a script code (e.g.
  // `MaterialLocalizationZh`).

  // We also generate one subclass for each locale with a country code (e.g.
  // `MaterialLocalizationEnGb`). Their superclasses are the aforementioned
  // language classes for the same locale but without a country code (e.g.
  // `MaterialLocalizationEn`).

  // If scriptCodes for a language are defined, we expect a scriptCode to be
  // defined for locales that contain a countryCode. The superclass becomes
  // the script subclass (e.g. `MaterialLocalizationZhHant`) and the generated
  // subclass will also contain the script code (e.g. `MaterialLocalizationZhHantTW`).

  // When scriptCodes are not defined for languages that use scriptCodes to distinguish
  // between significantly differing scripts, we assume the scriptCodes in the
  // [LocaleInfo.fromString] factory and add it to the [LocaleInfo]. We then generate
  // the script classes based on the first locale that we assume to use the script.

  final List<String> allKeys = allResourceIdentifiers.toList()..sort();
  final List<String> languageCodes = languageToLocales.keys.toList()..sort();
  final canonicalLocale = LocaleInfo.fromString('en');
  for (final languageName in languageCodes) {
    final languageLocale = LocaleInfo.fromString(languageName);
    generatedClassNames?.add('$generatedClassPrefix${languageLocale.camelCase()}');
    output.writeln(
      generateClassDeclaration(
        languageLocale,
        generatedClassPrefix,
        baseClass,
        deprecatedReplacementPackage: deprecatedReplacementPackage,
      ),
    );
    output.writeln(generateConstructor(languageLocale));

    final Map<String, String> languageResources = localeToResources[languageLocale]!;
    for (final key in allKeys) {
      final attributes = localeToResourceAttributes[canonicalLocale]![key] as Map<String, dynamic>?;
      output.writeln(generateGetter(key, languageResources[key], attributes, languageLocale));
    }
    output.writeln('}');
    var countryCodeCount = 0;
    var scriptCodeCount = 0;
    if (languageToScriptCodes.containsKey(languageName)) {
      scriptCodeCount = languageToScriptCodes[languageName]!.length;
      // Language has scriptCodes, so we need to properly fallback countries to corresponding
      // script default values before language default values.
      for (final String scriptCode in languageToScriptCodes[languageName]!) {
        final scriptBaseLocale = LocaleInfo.fromString('${languageName}_$scriptCode');
        generatedClassNames?.add('$generatedClassPrefix${scriptBaseLocale.camelCase()}');
        output.writeln(
          generateClassDeclaration(
            scriptBaseLocale,
            generatedClassPrefix,
            '$generatedClassPrefix${languageLocale.camelCase()}',
            deprecatedReplacementPackage: deprecatedReplacementPackage,
          ),
        );
        output.writeln(generateConstructorForCountrySubClass(scriptBaseLocale));
        final Map<String, String> scriptResources = localeToResources[scriptBaseLocale]!;
        for (final String key in scriptResources.keys.toList()..sort()) {
          if (languageResources[key] == scriptResources[key]) {
            continue;
          }
          final attributes =
              localeToResourceAttributes[canonicalLocale]![key] as Map<String, dynamic>?;
          output.writeln(generateGetter(key, scriptResources[key], attributes, languageLocale));
        }
        output.writeln('}');

        final List<LocaleInfo> localeCodes = languageToLocales[languageName]!..sort();
        for (final locale in localeCodes) {
          if (locale.originalString == languageName) {
            continue;
          }
          if (locale.originalString == '${languageName}_$scriptCode') {
            continue;
          }
          if (locale.scriptCode != scriptCode) {
            continue;
          }
          countryCodeCount += 1;
          generatedClassNames?.add('$generatedClassPrefix${locale.camelCase()}');
          output.writeln(
            generateClassDeclaration(
              locale,
              generatedClassPrefix,
              '$generatedClassPrefix${scriptBaseLocale.camelCase()}',
              deprecatedReplacementPackage: deprecatedReplacementPackage,
            ),
          );
          output.writeln(generateConstructorForCountrySubClass(locale));
          final Map<String, String> localeResources = localeToResources[locale]!;
          for (final String key in localeResources.keys) {
            // When script fallback contains the key, we compare to it instead of language fallback.
            if (scriptResources.containsKey(key)
                ? scriptResources[key] == localeResources[key]
                : languageResources[key] == localeResources[key]) {
              continue;
            }
            final attributes =
                localeToResourceAttributes[canonicalLocale]![key] as Map<String, dynamic>?;
            output.writeln(generateGetter(key, localeResources[key], attributes, languageLocale));
          }
          output.writeln('}');
        }
      }
    } else {
      // No scriptCode. Here, we do not compare against script default (because it
      // doesn't exist).
      final List<LocaleInfo> localeCodes = languageToLocales[languageName]!..sort();
      for (final locale in localeCodes) {
        if (locale.originalString == languageName) {
          continue;
        }
        countryCodeCount += 1;
        final Map<String, String> localeResources = localeToResources[locale]!;
        generatedClassNames?.add('$generatedClassPrefix${locale.camelCase()}');
        output.writeln(
          generateClassDeclaration(
            locale,
            generatedClassPrefix,
            '$generatedClassPrefix${languageLocale.camelCase()}',
            deprecatedReplacementPackage: deprecatedReplacementPackage,
          ),
        );
        output.writeln(generateConstructorForCountrySubClass(locale));
        for (final String key in localeResources.keys) {
          if (languageResources[key] == localeResources[key]) {
            continue;
          }
          final attributes =
              localeToResourceAttributes[canonicalLocale]![key] as Map<String, dynamic>?;
          output.writeln(generateGetter(key, localeResources[key], attributes, languageLocale));
        }
        output.writeln('}');
      }
    }

    final scriptCodeMessage = scriptCodeCount == 0
        ? ''
        : ' and $scriptCodeCount script${scriptCodeCount == 1 ? '' : 's'}';
    if (countryCodeCount == 0) {
      if (scriptCodeCount == 0) {
        supportedLocales.writeln('///  * `$languageName` - ${describeLocale(languageName)}');
      } else {
        supportedLocales.writeln(
          '///  * `$languageName` - ${describeLocale(languageName)} (plus $scriptCodeCount script${scriptCodeCount == 1 ? '' : 's'})',
        );
      }
    } else if (countryCodeCount == 1) {
      supportedLocales.writeln(
        '///  * `$languageName` - ${describeLocale(languageName)} (plus one country variation$scriptCodeMessage)',
      );
    } else {
      supportedLocales.writeln(
        '///  * `$languageName` - ${describeLocale(languageName)} (plus $countryCodeCount country variations$scriptCodeMessage)',
      );
    }
  }

  // Generate the factory function. Given a Locale it returns the corresponding
  // base class implementation.
  final supportedLanguagesDeprecation = deprecatedReplacementPackage != null
      ? '''
@Deprecated(
  'Use $supportedLanguagesConstant from $deprecatedReplacementPackage instead. '
  'This feature was deprecated after v3.47.0-0.0.pre.',
)
'''
      : '';
  final factoryDeprecation = deprecatedReplacementPackage != null
      ? '''
@Deprecated(
  'Use $factoryName from $deprecatedReplacementPackage instead. '
  'This feature was deprecated after v3.47.0-0.0.pre.',
)
'''
      : '';
  output.writeln('''

/// The set of supported languages, as language code strings.
///
/// The [$baseClass.delegate] can generate localizations for
/// any [Locale] with a language code from this set, regardless of the region.
/// Some regions have specific support (e.g. `de` covers all forms of German,
/// but there is support for `de-CH` specifically to override some of the
/// translations for Switzerland).
///
/// See also:
///
///  * [$factoryName], whose documentation describes these values.
${supportedLanguagesDeprecation}final Set<String> $supportedLanguagesConstant = HashSet<String>.from(const <String>[
${languageCodes.map<String>((String value) => "  '$value', // ${describeLocale(value)}").toList().join('\n')}
]);

/// Creates a [$baseClass] instance for the given `locale`.
///
/// All of the function's arguments except `locale` will be passed to the [
/// $baseClass] constructor. (The `localeName` argument of that
/// constructor is specified by the actual subclass constructor by this
/// function.)
///
/// The following locales are supported by this package:
///
/// {@template $supportedLanguagesDocMacro}
$supportedLocales/// {@endtemplate}
///
/// Generally speaking, this method is only intended to be used by
/// [$baseClass.delegate].
$factoryDeprecation$factoryDeclaration
  switch (locale.languageCode) {''');
  for (final String language in languageToLocales.keys) {
    // Only one instance of the language.
    if (languageToLocales[language]!.length == 1) {
      output.writeln(
        '''
    case '$language':
      return ${callsFactoryWithConst ? 'const ' : ''}$generatedClassPrefix${languageToLocales[language]![0].camelCase()}($factoryArguments);''',
      );
    } else if (!languageToScriptCodes.containsKey(language)) {
      // Does not distinguish between scripts. Switch on countryCode directly.
      output.writeln('''
    case '$language': {
      switch (locale.countryCode) {''');
      for (final LocaleInfo locale in languageToLocales[language]!) {
        if (locale.originalString == language) {
          continue;
        }
        assert(locale.length > 1);
        final String countryCode = locale.countryCode!;
        output.writeln(
          '''
        case '$countryCode':
          return ${callsFactoryWithConst ? 'const ' : ''}$generatedClassPrefix${locale.camelCase()}($factoryArguments);''',
        );
      }
      output.writeln('''
      }
      return ${callsFactoryWithConst ? 'const ' : ''}$generatedClassPrefix${LocaleInfo.fromString(language).camelCase()}($factoryArguments);
    }''');
    } else {
      // Language has scriptCode, add additional switch logic.
      var hasCountryCode = false;
      output.writeln('''
    case '$language': {
      switch (locale.scriptCode) {''');
      for (final String scriptCode in languageToScriptCodes[language]!) {
        final scriptLocale = LocaleInfo.fromString('${language}_$scriptCode');
        output.writeln('''
        case '$scriptCode': {''');
        if (languageAndScriptToCountryCodes.containsKey(scriptLocale)) {
          output.writeln('''
          switch (locale.countryCode) {''');
          for (final LocaleInfo locale in languageToLocales[language]!) {
            if (locale.countryCode == null) {
              continue;
            } else {
              hasCountryCode = true;
            }
            if (locale.originalString == language) {
              continue;
            }
            if (locale.scriptCode != scriptCode && locale.scriptCode != null) {
              continue;
            }
            final String countryCode = locale.countryCode!;
            output.writeln(
              '''
            case '$countryCode':
              return ${callsFactoryWithConst ? 'const ' : ''}$generatedClassPrefix${locale.camelCase()}($factoryArguments);''',
            );
          }
        }
        // Return a fallback locale that matches scriptCode, but not countryCode.
        //
        // Explicitly defined scriptCode fallback:
        if (languageToLocales[language]!.contains(scriptLocale)) {
          if (languageAndScriptToCountryCodes.containsKey(scriptLocale)) {
            output.writeln('''
          }''');
          }
          output.writeln('''
          return ${callsFactoryWithConst ? 'const ' : ''}$generatedClassPrefix${scriptLocale.camelCase()}($factoryArguments);
        }''');
        } else {
          // Not Explicitly defined, fallback to first locale with the same language and
          // script:
          for (final LocaleInfo locale in languageToLocales[language]!) {
            if (locale.scriptCode != scriptCode) {
              continue;
            }
            if (languageAndScriptToCountryCodes.containsKey(scriptLocale)) {
              output.writeln('''
          }''');
            }
            output.writeln('''
          return ${callsFactoryWithConst ? 'const ' : ''}$generatedClassPrefix${scriptLocale.camelCase()}($factoryArguments);
        }''');
            break;
          }
        }
      }
      output.writeln('''
      }''');
      if (hasCountryCode) {
        output.writeln('''
      switch (locale.countryCode) {''');
        for (final LocaleInfo locale in languageToLocales[language]!) {
          if (locale.originalString == language) {
            continue;
          }
          assert(locale.length > 1);
          if (locale.countryCode == null) {
            continue;
          }
          final String countryCode = locale.countryCode!;
          output.writeln(
            '''
        case '$countryCode':
          return ${callsFactoryWithConst ? 'const ' : ''}$generatedClassPrefix${locale.camelCase()}($factoryArguments);''',
          );
        }
        output.writeln('''
      }''');
      }
      output.writeln('''
      return ${callsFactoryWithConst ? 'const ' : ''}$generatedClassPrefix${LocaleInfo.fromString(language).camelCase()}($factoryArguments);
    }''');
    }
  }
  output.writeln('''
  }
  assert(false, '$factoryName() called for unsupported locale "\$locale"');
  return null;
}''');

  return output.toString();
}

/// Returns the appropriate type for getters with the given attributes.
///
/// Typically "String", but some (e.g. "timeOfDayFormat") return enums.
///
/// Used by [generateGetter] below.
String generateType(Map<String, dynamic>? attributes) {
  final bool optional = attributes?.containsKey('optional') ?? false;
  final String type = switch (attributes?['x-flutter-type']) {
    'icuShortTimePattern' => 'TimeOfDayFormat',
    'scriptCategory' => 'ScriptCategory',
    _ => 'String',
  };
  return type + (optional ? '?' : '');
}

/// Returns the appropriate name for getters with the given attributes.
///
/// Typically this is the key unmodified, but some have parameters, and
/// the GlobalMaterialLocalizations class does the substitution, and for
/// those we have to therefore provide an alternate name.
///
/// Used by [generateGetter] below.
String generateKey(String key, Map<String, dynamic>? attributes) {
  if (attributes != null) {
    if (attributes.containsKey('parameters')) {
      return '${key}Raw';
    }
    switch (attributes['x-flutter-type'] as String?) {
      case 'icuShortTimePattern':
        return '${key}Raw';
    }
  }
  if (key == 'datePickerDateOrder') {
    return 'datePickerDateOrderString';
  }
  if (key == 'datePickerDateTimeOrder') {
    return 'datePickerDateTimeOrderString';
  }
  return key;
}

const Map<String, String> _icuTimeOfDayToEnum = <String, String>{
  'HH:mm': 'TimeOfDayFormat.HH_colon_mm',
  'HH.mm': 'TimeOfDayFormat.HH_dot_mm',
  "HH 'h' mm": 'TimeOfDayFormat.frenchCanadian',
  'HH:mm น.': 'TimeOfDayFormat.HH_colon_mm',
  'H:mm': 'TimeOfDayFormat.H_colon_mm',
  'h:mm a': 'TimeOfDayFormat.h_colon_mm_space_a',
  'a h:mm': 'TimeOfDayFormat.a_space_h_colon_mm',
  'ah:mm': 'TimeOfDayFormat.a_space_h_colon_mm',
};

const Map<String, String> _scriptCategoryToEnum = <String, String>{
  'English-like': 'ScriptCategory.englishLike',
  'dense': 'ScriptCategory.dense',
  'tall': 'ScriptCategory.tall',
};

/// Returns the literal that describes the value returned by getters
/// with the given attributes.
///
/// This handles cases like the value being a literal `null`, an enum, and so
/// on. The default is to treat the value as a string and escape it and quote
/// it.
///
/// Used by [generateGetter] below.
String? generateValue(String? value, Map<String, dynamic>? attributes, LocaleInfo locale) {
  if (value == null) {
    return null;
  }
  // cupertino_en.arb doesn't use x-flutter-type.
  if (attributes != null) {
    switch (attributes['x-flutter-type'] as String?) {
      case 'icuShortTimePattern':
        if (!_icuTimeOfDayToEnum.containsKey(value)) {
          throw Exception(
            '"$value" is not one of the ICU short time patterns supported '
            'by the material library. Here is the list of supported '
            'patterns:\n  ${_icuTimeOfDayToEnum.keys.join('\n  ')}',
          );
        }
        return _icuTimeOfDayToEnum[value];
      case 'scriptCategory':
        if (!_scriptCategoryToEnum.containsKey(value)) {
          throw Exception(
            '"$value" is not one of the scriptCategory values supported '
            'by the material library. Here is the list of supported '
            'values:\n  ${_scriptCategoryToEnum.keys.join('\n  ')}',
          );
        }
        return _scriptCategoryToEnum[value];
    }
  }
  return generateEncodedString(locale.languageCode, value);
}

/// Combines [generateType], [generateKey], and [generateValue] to return
/// the source of getters for the GlobalMaterialLocalizations subclass.
/// The locale is the locale for which the getter is being generated.
String generateGetter(
  String key,
  String? value,
  Map<String, dynamic>? attributes,
  LocaleInfo locale,
) {
  final String type = generateType(attributes);
  key = generateKey(key, attributes);
  final String? generatedValue = generateValue(value, attributes, locale);
  return '''

  @override
  $type get $key => $generatedValue;''';
}

void main(List<String> rawArgs) {
  checkCwdIsRepoRoot('gen_localizations');
  final GeneratorOptions options = parseArgs(rawArgs);

  // filenames are assumed to end in "prefix_lc.arb" or "prefix_lc_cc.arb", where prefix
  // is the 2nd command line argument, lc is a language code and cc is the country
  // code. In most cases both codes are just two characters.

  final directory = Directory(path.join('packages', 'flutter_localizations', 'lib', 'src', 'l10n'));
  final widgetsFilenameRE = RegExp(r'widgets_(\w+)\.arb$');
  final materialFilenameRE = RegExp(r'material_(\w+)\.arb$');
  final cupertinoFilenameRE = RegExp(r'cupertino_(\w+)\.arb$');

  try {
    validateEnglishLocalizations(File(path.join(directory.path, 'widgets_en.arb')));
    validateEnglishLocalizations(File(path.join(directory.path, 'material_en.arb')));
    validateEnglishLocalizations(File(path.join(directory.path, 'cupertino_en.arb')));
  } on ValidationError catch (exception) {
    exitWithError('$exception');
  }

  // Only rewrite material_kn.arb and cupertino_en.arb if overwriting the
  // Material and Cupertino localizations files.
  if (options.writeToFile) {
    // Encodes the material_kn.arb file and the cupertino_en.arb files before
    // generating localizations. This prevents a subset of Emacs users from
    // crashing when opening up the Flutter source code.
    // See https://github.com/flutter/flutter/issues/36704 for more context.
    encodeKnArbFiles(directory);
  }

  precacheLanguageAndRegionTags();

  // Maps of locales to resource key/value pairs for Widgets ARBs.
  final widgetsLocaleToResources = <LocaleInfo, Map<String, String>>{};
  // Maps of locales to resource key/attributes pairs for Widgets ARBs.
  // https://github.com/googlei18n/app-resource-bundle/wiki/ApplicationResourceBundleSpecification#resource-attributes
  final widgetsLocaleToResourceAttributes = <LocaleInfo, Map<String, dynamic>>{};

  // Maps of locales to resource key/value pairs for Material ARBs.
  final materialLocaleToResources = <LocaleInfo, Map<String, String>>{};
  // Maps of locales to resource key/attributes pairs for Material ARBs.
  // https://github.com/googlei18n/app-resource-bundle/wiki/ApplicationResourceBundleSpecification#resource-attributes
  final materialLocaleToResourceAttributes = <LocaleInfo, Map<String, dynamic>>{};

  // Maps of locales to resource key/value pairs for Cupertino ARBs.
  final cupertinoLocaleToResources = <LocaleInfo, Map<String, String>>{};
  // Maps of locales to resource key/attributes pairs for Cupertino ARBs.
  // https://github.com/googlei18n/app-resource-bundle/wiki/ApplicationResourceBundleSpecification#resource-attributes
  final cupertinoLocaleToResourceAttributes = <LocaleInfo, Map<String, dynamic>>{};

  loadMatchingArbsIntoBundleMaps(
    directory: directory,
    filenamePattern: widgetsFilenameRE,
    localeToResources: widgetsLocaleToResources,
    localeToResourceAttributes: widgetsLocaleToResourceAttributes,
  );
  loadMatchingArbsIntoBundleMaps(
    directory: directory,
    filenamePattern: materialFilenameRE,
    localeToResources: materialLocaleToResources,
    localeToResourceAttributes: materialLocaleToResourceAttributes,
  );
  loadMatchingArbsIntoBundleMaps(
    directory: directory,
    filenamePattern: cupertinoFilenameRE,
    localeToResources: cupertinoLocaleToResources,
    localeToResourceAttributes: cupertinoLocaleToResourceAttributes,
  );

  try {
    validateLocalizations(
      widgetsLocaleToResources,
      widgetsLocaleToResourceAttributes,
      removeUndefined: options.removeUndefined,
    );
    validateLocalizations(
      materialLocaleToResources,
      materialLocaleToResourceAttributes,
      removeUndefined: options.removeUndefined,
    );
    validateLocalizations(
      cupertinoLocaleToResources,
      cupertinoLocaleToResourceAttributes,
      removeUndefined: options.removeUndefined,
    );
  } on ValidationError catch (exception) {
    exitWithError('$exception');
  }
  if (options.removeUndefined) {
    removeUndefinedLocalizations(widgetsLocaleToResources);
    removeUndefinedLocalizations(materialLocaleToResources);
    removeUndefinedLocalizations(cupertinoLocaleToResources);
  }

  final String? widgetsLocalizations = options.writeToFile || !options.cupertinoOnly
      ? generateArbBasedLocalizationSubclasses(
          localeToResources: widgetsLocaleToResources,
          localeToResourceAttributes: widgetsLocaleToResourceAttributes,
          generatedClassPrefix: 'WidgetsLocalization',
          baseClass: 'GlobalWidgetsLocalizations',
          generateHeader: generateWidgetsHeader,
          generateConstructor: generateWidgetsConstructor,
          generateConstructorForCountrySubClass: generateWidgetsConstructorForCountrySubclass,
          factoryName: widgetsFactoryName,
          factoryDeclaration: widgetsFactoryDeclaration,
          callsFactoryWithConst: true,
          factoryArguments: widgetsFactoryArguments,
          supportedLanguagesConstant: widgetsSupportedLanguagesConstant,
          supportedLanguagesDocMacro: widgetsSupportedLanguagesDocMacro,
        )
      : null;
  final materialGeneratedClasses = <String>{};
  final String? materialLocalizations = options.writeToFile || !options.cupertinoOnly
      ? generateArbBasedLocalizationSubclasses(
          localeToResources: materialLocaleToResources,
          localeToResourceAttributes: materialLocaleToResourceAttributes,
          generatedClassPrefix: 'MaterialLocalization',
          baseClass: 'GlobalMaterialLocalizations',
          generateHeader: generateMaterialHeader,
          generateConstructor: generateMaterialConstructor,
          factoryName: materialFactoryName,
          factoryDeclaration: materialFactoryDeclaration,
          callsFactoryWithConst: false,
          factoryArguments: materialFactoryArguments,
          supportedLanguagesConstant: materialSupportedLanguagesConstant,
          supportedLanguagesDocMacro: materialSupportedLanguagesDocMacro,
          deprecatedReplacementPackage: 'package:material_ui/material_ui.dart',
          generatedClassNames: materialGeneratedClasses,
        )
      : null;
  final cupertinoGeneratedClasses = <String>{};
  final String? cupertinoLocalizations = options.writeToFile || !options.materialOnly
      ? generateArbBasedLocalizationSubclasses(
          localeToResources: cupertinoLocaleToResources,
          localeToResourceAttributes: cupertinoLocaleToResourceAttributes,
          generatedClassPrefix: 'CupertinoLocalization',
          baseClass: 'GlobalCupertinoLocalizations',
          generateHeader: generateCupertinoHeader,
          generateConstructor: generateCupertinoConstructor,
          factoryName: cupertinoFactoryName,
          factoryDeclaration: cupertinoFactoryDeclaration,
          callsFactoryWithConst: false,
          factoryArguments: cupertinoFactoryArguments,
          supportedLanguagesConstant: cupertinoSupportedLanguagesConstant,
          supportedLanguagesDocMacro: cupertinoSupportedLanguagesDocMacro,
          deprecatedReplacementPackage: 'package:cupertino_ui/cupertino_ui.dart',
          generatedClassNames: cupertinoGeneratedClasses,
        )
      : null;

  if (options.writeToFile) {
    final widgetsLocalizationsFile = File(
      path.join(directory.path, 'generated_widgets_localizations.dart'),
    );
    widgetsLocalizationsFile.writeAsStringSync(widgetsLocalizations!, flush: true);
    final materialLocalizationsFile = File(
      path.join(directory.path, 'generated_material_localizations.dart'),
    );
    materialLocalizationsFile.writeAsStringSync(materialLocalizations!, flush: true);
    final cupertinoLocalizationsFile = File(
      path.join(directory.path, 'generated_cupertino_localizations.dart'),
    );
    cupertinoLocalizationsFile.writeAsStringSync(cupertinoLocalizations!, flush: true);

    final fixDataDir = Directory(path.join(directory.parent.parent.path, 'fix_data'));
    fixDataDir.createSync(recursive: true);
    File(path.join(fixDataDir.path, 'fix_material_localizations.yaml')).writeAsStringSync(
      generateLocalizationFixData(
        baseClass: 'GlobalMaterialLocalizations',
        supportedLanguagesConstant: materialSupportedLanguagesConstant,
        factoryName: materialFactoryName,
        generatedClassNames: materialGeneratedClasses,
        replacementPackageUri: 'package:material_ui/material_ui.dart',
      ),
      flush: true,
    );
    File(path.join(fixDataDir.path, 'fix_cupertino_localizations.yaml')).writeAsStringSync(
      generateLocalizationFixData(
        baseClass: 'GlobalCupertinoLocalizations',
        supportedLanguagesConstant: cupertinoSupportedLanguagesConstant,
        factoryName: cupertinoFactoryName,
        generatedClassNames: cupertinoGeneratedClasses,
        replacementPackageUri: 'package:cupertino_ui/cupertino_ui.dart',
      ),
      flush: true,
    );
  } else {
    if (options.cupertinoOnly) {
      stdout.write(cupertinoLocalizations);
    } else if (options.materialOnly) {
      stdout.write(materialLocalizations);
    } else if (options.widgetsOnly) {
      stdout.write(widgetsLocalizations);
    } else {
      stdout.write(widgetsLocalizations);
      stdout.write(materialLocalizations);
      stdout.write(cupertinoLocalizations);
    }
  }
}

String generateLocalizationFixData({
  required String baseClass,
  required String supportedLanguagesConstant,
  required String factoryName,
  required Set<String> generatedClassNames,
  required String replacementPackageUri,
}) {
  final buffer = StringBuffer('''
# 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.

# THIS FILE IS GENERATED. DO NOT EDIT BY HAND.
#
# This file is generated by:
#   dart dev/tools/localization/bin/gen_localizations.dart --overwrite

# For details regarding the *Flutter Fix* feature, see
# https://flutter.dev/to/flutter-fix

# Every fix must be tested. See the
# flutter/packages/flutter_localizations/test_fixes/README.md file for
# instructions on testing these data driven fixes.

# For documentation about this file format, see
# https://dart.dev/go/data-driven-fixes.

version: 1
transforms:
  - title: "Migrate to '$replacementPackageUri'"
    date: 2026-09-17
    element:
      uris: ['flutter_localizations.dart']
      class: '$baseClass'
    changes:
      - kind: 'replacedBy'
        newElement:
          uris: ['$replacementPackageUri']
          class: '$baseClass'

  - title: "Migrate to '$replacementPackageUri'"
    date: 2026-09-17
    element:
      uris: ['flutter_localizations.dart']
      variable: '$supportedLanguagesConstant'
    changes:
      - kind: 'replacedBy'
        newElement:
          uris: ['$replacementPackageUri']
          variable: '$supportedLanguagesConstant'

  - title: "Migrate to '$replacementPackageUri'"
    date: 2026-09-17
    element:
      uris: ['flutter_localizations.dart']
      function: '$factoryName'
    changes:
      - kind: 'replacedBy'
        newElement:
          uris: ['$replacementPackageUri']
          function: '$factoryName'
''');

  for (final className in generatedClassNames) {
    buffer.write('''

  - title: "Migrate to '$replacementPackageUri'"
    date: 2026-09-17
    element:
      uris: ['flutter_localizations.dart']
      class: '$className'
    changes:
      - kind: 'replacedBy'
        newElement:
          uris: ['$replacementPackageUri']
          class: '$className'
''');
  }

  return buffer.toString();
}
