// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This program generates getMaterialTranslation() and getCupertinoTranslation()
// functions that look up the translations provided by the arb files. The
// returned value is a generated instance of a GlobalMaterialLocalizations or
// GlobalCupertinoLocalizations object that corresponds to a single locale.
//
// The *.arb files are in packages/material_ui/lib/l10n and
// packages/cupertino_ui/lib/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 script/l10n/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 script/l10n/bin/gen_localizations.dart --remove-undefined
// ```
//
// If the data looks good, use the `-w` or `--overwrite` option to overwrite the
// generated_material_localizations.dart and
// generated_cupertino_localizations.dart files in
// packages/flutter_localizations/lib/l10n/:
//
// ```
// dart script/l10n/bin/gen_localizations.dart --overwrite
// ```

import 'dart:io';

import 'package:l10n/gen_cupertino_localizations.dart';
import 'package:l10n/gen_material_localizations.dart';
import 'package:l10n/localizations_utils.dart';
import 'package:l10n/localizations_validator.dart';

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

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,
}) {
  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 script/l10n/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);
    output.writeln(generateClassDeclaration(languageLocale, generatedClassPrefix, baseClass));
    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');
        output.writeln(
          generateClassDeclaration(
            scriptBaseLocale,
            generatedClassPrefix,
            '$generatedClassPrefix${languageLocale.camelCase()}',
          ),
        );
        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;
          output.writeln(
            generateClassDeclaration(
              locale,
              generatedClassPrefix,
              '$generatedClassPrefix${scriptBaseLocale.camelCase()}',
            ),
          );
          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]!;
        output.writeln(
          generateClassDeclaration(
            locale,
            generatedClassPrefix,
            '$generatedClassPrefix${languageLocale.camelCase()}',
          ),
        );
        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.
  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.
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].
$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 materialDirectory = Directory(path.join('packages', 'material_ui', 'lib', 'src', 'l10n'));
  final cupertinoDirectory = Directory(path.join('packages', 'cupertino_ui', 'lib', 'src', 'l10n'));
  final materialFilenameRE = RegExp(r'material_(\w+)\.arb$');
  final cupertinoFilenameRE = RegExp(r'cupertino_(\w+)\.arb$');

  try {
    validateEnglishLocalizations(File(path.join(materialDirectory.path, 'material_en.arb')));
    validateEnglishLocalizations(File(path.join(cupertinoDirectory.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(materialDirectory, cupertinoDirectory);
  }

  precacheLanguageAndRegionTags();

  // 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: materialDirectory,
    filenamePattern: materialFilenameRE,
    localeToResources: materialLocaleToResources,
    localeToResourceAttributes: materialLocaleToResourceAttributes,
  );
  loadMatchingArbsIntoBundleMaps(
    directory: cupertinoDirectory,
    filenamePattern: cupertinoFilenameRE,
    localeToResources: cupertinoLocaleToResources,
    localeToResourceAttributes: cupertinoLocaleToResourceAttributes,
  );

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

  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,
        )
      : null;
  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,
        )
      : null;

  if (options.writeToFile) {
    final materialLocalizationsFile = File(
      path.join(materialDirectory.path, 'generated_material_localizations.dart'),
    );
    materialLocalizationsFile.writeAsStringSync(materialLocalizations!, flush: true);
    final cupertinoLocalizationsFile = File(
      path.join(cupertinoDirectory.path, 'generated_cupertino_localizations.dart'),
    );
    cupertinoLocalizationsFile.writeAsStringSync(cupertinoLocalizations!, flush: true);
  } else {
    if (options.cupertinoOnly) {
      stdout.write(cupertinoLocalizations);
    } else if (options.materialOnly) {
      stdout.write(materialLocalizations);
    } else {
      stdout.write(materialLocalizations);
      stdout.write(cupertinoLocalizations);
    }
  }
}
