// 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:async';
import 'dart:convert';
import 'dart:io';

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

import '../localizations_utils.dart';

const String _kCommandName = 'gen_date_localizations.dart';

// Used to let _jsonToMap know what locale it's date symbols converting for.
// Date symbols for the Kannada locale ('kn') are handled specially because
// some of the strings contain characters that can crash Emacs on Linux.
// See packages/flutter_localizations/lib/src/l10n/README for more information.
String? currentLocale;

/// This program extracts localized date symbols and patterns from the intl
/// package for the subset of locales supported by the flutter_localizations
/// package.
///
/// The extracted data is written into:
///   packages/flutter_localizations/lib/src/l10n/generated_date_localizations.dart
///
/// ## 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_date_localizations.dart
/// ```
///
/// If the data looks good, use the `--overwrite` option to overwrite the
/// lib/src/l10n/date_localizations.dart file:
///
/// ```
/// dart dev/tools/localization/bin/gen_date_localizations.dart --overwrite
/// ```
Future<void> main(List<String> rawArgs) async {
  checkCwdIsRepoRoot(_kCommandName);

  final bool writeToFile = parseArgs(rawArgs).writeToFile;

  final File dotPackagesFile = File(path.join('packages', 'flutter_localizations', '.packages'));
  final bool dotPackagesExists = dotPackagesFile.existsSync();

  if (!dotPackagesExists) {
    exitWithError(
      'File not found: ${dotPackagesFile.path}. $_kCommandName must be run '
      'after a successful "flutter update-packages".'
    );
  }

  final String pathToIntl = dotPackagesFile
    .readAsStringSync()
    .split('\n')
    .firstWhere(
      (String line) => line.startsWith('intl:'),
      orElse: () {
        exitWithError('intl dependency not found in ${dotPackagesFile.path}');
        return ''; // unreachable
      },
    )
    .split(':')
    .last;

  final Directory dateSymbolsDirectory = Directory(path.join(pathToIntl, 'src', 'data', 'dates', 'symbols'));
  final Map<String, File> symbolFiles = _listIntlData(dateSymbolsDirectory);
  final Directory datePatternsDirectory = Directory(path.join(pathToIntl, 'src', 'data', 'dates', 'patterns'));
  final Map<String, File> patternFiles = _listIntlData(datePatternsDirectory);
  final StringBuffer buffer = StringBuffer();
  final Set<String> supportedLocales = _supportedLocales();

  buffer.writeln(
'''
// 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 has been automatically generated. Please do not edit it manually.
// To regenerate run (omit --overwrite to print to console instead of the file):
// dart --enable-asserts dev/tools/localization/bin/gen_date_localizations.dart --overwrite

import 'package:intl/date_symbols.dart' as intl;

'''
);
  buffer.writeln('''
/// The subset of date symbols supported by the intl package which are also
/// supported by flutter_localizations.''');
  buffer.writeln('final Map<String, intl.DateSymbols> dateSymbols = <String, intl.DateSymbols> {');
  symbolFiles.forEach((String locale, File data) {
    currentLocale = locale;
    if (supportedLocales.contains(locale)) {
      final Map<String, Object?> objData =  json.decode(data.readAsStringSync()) as Map<String, Object?>;
      buffer.writeln("'$locale': intl.DateSymbols(");
      objData.forEach((String key, Object? value) {
        if (value == null) {
          return;
        }
        buffer.writeln(_jsonToConstructorEntry(key, value));
      });
      buffer.writeln('),');
    }
  });
  currentLocale = null;
  buffer.writeln('};');

  // Code that uses datePatterns expects it to contain values of type
  // Map<String, String> not Map<String, dynamic>.
  buffer.writeln('''
/// The subset of date patterns supported by the intl package which are also
/// supported by flutter_localizations.''');
  buffer.writeln('const Map<String, Map<String, String>> datePatterns = <String, Map<String, String>> {');
  patternFiles.forEach((String locale, File data) {
    if (supportedLocales.contains(locale)) {
      final Map<String, dynamic> patterns = json.decode(data.readAsStringSync()) as Map<String, dynamic>;
      buffer.writeln("'$locale': <String, String>{");
      patterns.forEach((String key, dynamic value) {
        assert(value is String);
        buffer.writeln(_jsonToMapEntry(key, value));
      });
      buffer.writeln('},');
    }
  });
  buffer.writeln('};');

  if (writeToFile) {
    final File dateLocalizationsFile = File(path.join('packages', 'flutter_localizations', 'lib', 'src', 'l10n', 'generated_date_localizations.dart'));
    dateLocalizationsFile.writeAsStringSync(buffer.toString());
    final String extension = Platform.isWindows ? '.exe' : '';
    final ProcessResult result = Process.runSync(path.join('bin', 'cache', 'dart-sdk', 'bin', 'dart$extension'), <String>[
      'format',
      dateLocalizationsFile.path,
    ]);
    if (result.exitCode != 0) {
      print(result.exitCode);
      print(result.stdout);
      print(result.stderr);
    }
  } else {
    print(buffer);
  }
}

String _jsonToConstructorEntry(String key, dynamic value) {
  return '$key: ${_jsonToObject(value)},';
}

String _jsonToMapEntry(String key, dynamic value) {
  return "'$key': ${_jsonToMap(value)},";
}

String _jsonToObject(dynamic json) {
  if (json == null || json is num || json is bool) {
    return '$json';
  }

  if (json is String) {
    return generateEncodedString(currentLocale, json);
  }

  if (json is Iterable<Object?>) {
    final String type = json.first.runtimeType.toString();
    final StringBuffer buffer = StringBuffer('const <$type>[');
    for (final dynamic value in json) {
      buffer.writeln('${_jsonToMap(value)},');
    }
    buffer.write(']');
    return buffer.toString();
  }

  if (json is Map<String, dynamic>) {
    final StringBuffer buffer = StringBuffer('<String, Object>{');
    json.forEach((String key, dynamic value) {
      buffer.writeln(_jsonToMapEntry(key, value));
    });
    buffer.write('}');
    return buffer.toString();
  }

  throw 'Unsupported JSON type ${json.runtimeType} of value $json.';
}

String _jsonToMap(dynamic json) {
  if (json == null || json is num || json is bool) {
    return '$json';
  }

  if (json is String) {
    return generateEncodedString(currentLocale, json);
  }

  if (json is Iterable) {
    final StringBuffer buffer = StringBuffer('<String>[');
    for (final dynamic value in json) {
      buffer.writeln('${_jsonToMap(value)},');
    }
    buffer.write(']');
    return buffer.toString();
  }

  if (json is Map<String, dynamic>) {
    final StringBuffer buffer = StringBuffer('<String, Object>{');
    json.forEach((String key, dynamic value) {
      buffer.writeln(_jsonToMapEntry(key, value));
    });
    buffer.write('}');
    return buffer.toString();
  }

  throw 'Unsupported JSON type ${json.runtimeType} of value $json.';
}

Set<String> _supportedLocales() {
  // Assumes that en_US is a supported locale by default. Without this, usage
  // of the intl package APIs before Flutter populates its set of supported i18n
  // date patterns and symbols may cause problems.
  //
  // For more context, see https://github.com/flutter/flutter/issues/67644.
  final Set<String> supportedLocales = <String>{
    'en_US',
  };
  final RegExp filenameRE = RegExp(r'(?:material|cupertino)_(\w+)\.arb$');
  final Directory supportedLocalesDirectory = Directory(path.join('packages', 'flutter_localizations', 'lib', 'src', 'l10n'));
  for (final FileSystemEntity entity in supportedLocalesDirectory.listSync()) {
    final String filePath = entity.path;
    if (FileSystemEntity.isFileSync(filePath) && filenameRE.hasMatch(filePath)) {
      supportedLocales.add(filenameRE.firstMatch(filePath)![1]!);
    }
  }

  return supportedLocales;
}

Map<String, File> _listIntlData(Directory directory) {
  final Map<String, File> localeFiles = <String, File>{};
  final Iterable<File> files = directory
    .listSync()
    .whereType<File>()
    .where((File file) => file.path.endsWith('.json'));
  for (final File file in files) {
    final String locale = path.basenameWithoutExtension(file.path);
    localeFiles[locale] = file;
  }

  final List<String> locales = localeFiles.keys.toList(growable: false);
  locales.sort();
  return Map<String, File>.fromIterable(locales, value: (dynamic locale) => localeFiles[locale]!);
}
