// Copyright 2017 The Chromium 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:args/args.dart' as argslib;
import 'package:meta/meta.dart';

typedef HeaderGenerator = String Function(String regenerateInstructions);
typedef ConstructorGenerator = String Function(LocaleInfo locale);

/// Simple data class to hold parsed locale. Does not promise validity of any data.
class LocaleInfo implements Comparable<LocaleInfo> {
  LocaleInfo({
    this.languageCode,
    this.scriptCode,
    this.countryCode,
    this.length,
    this.originalString,
  });

  /// Simple parser. Expects the locale string to be in the form of 'language_script_COUNTRY'
  /// where the langauge is 2 characters, script is 4 characters with the first uppercase,
  /// and country is 2-3 characters and all uppercase.
  ///
  /// 'language_COUNTRY' or 'language_script' are also valid. Missing fields will be null.
  ///
  /// When `deriveScriptCode` is true, if [scriptCode] was unspecified, it will
  /// be derived from the [languageCode] and [countryCode] if possible.
  factory LocaleInfo.fromString(String locale, { bool deriveScriptCode = false }) {
    final List<String> codes = locale.split('_'); // [language, script, country]
    assert(codes.isNotEmpty && codes.length < 4);
    final String languageCode = codes[0];
    String scriptCode;
    String countryCode;
    int length = codes.length;
    String originalString = locale;
    if (codes.length == 2) {
      scriptCode = codes[1].length >= 4 ? codes[1] : null;
      countryCode = codes[1].length < 4 ? codes[1] : null;
    } else if (codes.length == 3) {
      scriptCode = codes[1].length > codes[2].length ? codes[1] : codes[2];
      countryCode = codes[1].length < codes[2].length ? codes[1] : codes[2];
    }
    assert(codes[0] != null && codes[0].isNotEmpty);
    assert(countryCode == null || countryCode.isNotEmpty);
    assert(scriptCode == null || scriptCode.isNotEmpty);

    /// Adds scriptCodes to locales where we are able to assume it to provide
    /// finer granularity when resolving locales.
    ///
    /// The basis of the assumptions here are based off of known usage of scripts
    /// across various countries. For example, we know Taiwan uses traditional (Hant)
    /// script, so it is safe to apply (Hant) to Taiwanese languages.
    if (deriveScriptCode && scriptCode == null) {
      switch (languageCode) {
        case 'zh': {
          if (countryCode == null) {
            scriptCode = 'Hans';
          }
          switch (countryCode) {
            case 'CN':
            case 'SG':
              scriptCode = 'Hans';
              break;
            case 'TW':
            case 'HK':
            case 'MO':
              scriptCode = 'Hant';
              break;
          }
          break;
        }
        case 'sr': {
          if (countryCode == null) {
            scriptCode = 'Cyrl';
          }
          break;
        }
      }
      // Increment length if we were able to assume a scriptCode.
      if (scriptCode != null) {
        length += 1;
      }
      // Update the base string to reflect assumed scriptCodes.
      originalString = languageCode;
      if (scriptCode != null)
        originalString += '_' + scriptCode;
      if (countryCode != null)
        originalString += '_' + countryCode;
    }

    return LocaleInfo(
      languageCode: languageCode,
      scriptCode: scriptCode,
      countryCode: countryCode,
      length: length,
      originalString: originalString,
    );
  }

  final String languageCode;
  final String scriptCode;
  final String countryCode;
  final int length;             // The number of fields. Ranges from 1-3.
  final String originalString;  // Original un-parsed locale string.

  @override
  bool operator ==(Object other) {
    if (!(other is LocaleInfo))
      return false;
    final LocaleInfo otherLocale = other;
    return originalString == otherLocale.originalString;
  }

  @override
  int get hashCode {
    return originalString.hashCode;
  }

  @override
  String toString() {
    return originalString;
  }

  @override
  int compareTo(LocaleInfo other) {
    return originalString.compareTo(other.originalString);
  }
}

/// Parse the data for a locale from a file, and store it in the [attributes]
/// and [resources] keys.
void loadMatchingArbsIntoBundleMaps({
  @required Directory directory,
  @required RegExp filenamePattern,
  @required Map<LocaleInfo, Map<String, String>> localeToResources,
  @required Map<LocaleInfo, Map<String, dynamic>> localeToResourceAttributes,
}) {
  assert(directory != null);
  assert(filenamePattern != null);
  assert(localeToResources != null);
  assert(localeToResourceAttributes != null);

  /// Set that holds the locales that were assumed from the existing locales.
  ///
  /// For example, when the data lacks data for zh_Hant, we will use the data of
  /// the first Hant Chinese locale as a default by repeating the data. If an
  /// explicit match is later found, we can reference this set to see if we should
  /// overwrite the existing assumed data.
  final Set<LocaleInfo> assumedLocales = <LocaleInfo>{};

  for (FileSystemEntity entity in directory.listSync()) {
    final String entityPath = entity.path;
    if (FileSystemEntity.isFileSync(entityPath) && filenamePattern.hasMatch(entityPath)) {
      final String localeString = filenamePattern.firstMatch(entityPath)[1];
      final File arbFile = File(entityPath);

      // Helper method to fill the maps with the correct data from file.
      void populateResources(LocaleInfo locale, File file) {
        final Map<String, String> resources = localeToResources[locale];
        final Map<String, dynamic> attributes = localeToResourceAttributes[locale];
        final Map<String, dynamic> bundle = json.decode(file.readAsStringSync());
        for (String key in bundle.keys) {
          // The ARB file resource "attributes" for foo are called @foo.
          if (key.startsWith('@'))
            attributes[key.substring(1)] = bundle[key];
          else
            resources[key] = bundle[key];
        }
      }
      // Only pre-assume scriptCode if there is a country or script code to assume off of.
      // When we assume scriptCode based on languageCode-only, we want this initial pass
      // to use the un-assumed version as a base class.
      LocaleInfo locale = LocaleInfo.fromString(localeString, deriveScriptCode: localeString.split('_').length > 1);
      // Allow overwrite if the existing data is assumed.
      if (assumedLocales.contains(locale)) {
        localeToResources[locale] = <String, String>{};
        localeToResourceAttributes[locale] = <String, dynamic>{};
        assumedLocales.remove(locale);
      } else {
        localeToResources[locale] ??= <String, String>{};
        localeToResourceAttributes[locale] ??= <String, dynamic>{};
      }
      populateResources(locale, arbFile);
      // Add an assumed locale to default to when there is no info on scriptOnly locales.
      locale = LocaleInfo.fromString(localeString, deriveScriptCode: true);
      if (locale.scriptCode != null) {
        final LocaleInfo scriptLocale = LocaleInfo.fromString(locale.languageCode + '_' + locale.scriptCode);
        if (!localeToResources.containsKey(scriptLocale)) {
          assumedLocales.add(scriptLocale);
          localeToResources[scriptLocale] ??= <String, String>{};
          localeToResourceAttributes[scriptLocale] ??= <String, dynamic>{};
          populateResources(scriptLocale, arbFile);
        }
      }
    }
  }
}

void exitWithError(String errorMessage) {
  assert(errorMessage != null);
  stderr.writeln('fatal: $errorMessage');
  exit(1);
}

void checkCwdIsRepoRoot(String commandName) {
  final bool isRepoRoot = Directory('.git').existsSync();

  if (!isRepoRoot) {
    exitWithError(
      '$commandName must be run from the root of the Flutter repository. The '
      'current working directory is: ${Directory.current.path}'
    );
  }
}

String camelCase(LocaleInfo locale) {
  return locale.originalString
    .split('_')
    .map<String>((String part) => part.substring(0, 1).toUpperCase() + part.substring(1).toLowerCase())
    .join('');
}

GeneratorOptions parseArgs(List<String> rawArgs) {
  final argslib.ArgParser argParser = argslib.ArgParser()
    ..addFlag(
      'overwrite',
      abbr: 'w',
      defaultsTo: false,
    );
  final argslib.ArgResults args = argParser.parse(rawArgs);
  final bool writeToFile = args['overwrite'];

  return GeneratorOptions(writeToFile: writeToFile);
}

class GeneratorOptions {
  GeneratorOptions({
    @required this.writeToFile,
  });

  final bool writeToFile;
}

const String registry = 'https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry';

// See also //master/tools/gen_locale.dart in the engine repo.
Map<String, List<String>> _parseSection(String section) {
  final Map<String, List<String>> result = <String, List<String>>{};
  List<String> lastHeading;
  for (String line in section.split('\n')) {
    if (line == '')
      continue;
    if (line.startsWith('  ')) {
      lastHeading[lastHeading.length - 1] = '${lastHeading.last}${line.substring(1)}';
      continue;
    }
    final int colon = line.indexOf(':');
    if (colon <= 0)
      throw 'not sure how to deal with "$line"';
    final String name = line.substring(0, colon);
    final String value = line.substring(colon + 2);
    lastHeading = result.putIfAbsent(name, () => <String>[]);
    result[name].add(value);
  }
  return result;
}

final Map<String, String> _languages = <String, String>{};
final Map<String, String> _regions = <String, String>{};
final Map<String, String> _scripts = <String, String>{};
const String kProvincePrefix = ', Province of ';
const String kParentheticalPrefix = ' (';

/// Prepares the data for the [describeLocale] method below.
///
/// The data is obtained from the official IANA registry.
Future<void> precacheLanguageAndRegionTags() async {
  final HttpClient client = HttpClient();
  final HttpClientRequest request = await client.getUrl(Uri.parse(registry));
  final HttpClientResponse response = await request.close();
  final String body = (await response.transform<String>(utf8.decoder).toList()).join('');
  client.close(force: true);
  final List<Map<String, List<String>>> sections = body.split('%%').skip(1).map<Map<String, List<String>>>(_parseSection).toList();
  for (Map<String, List<String>> section in sections) {
    assert(section.containsKey('Type'), section.toString());
    final String type = section['Type'].single;
    if (type == 'language' || type == 'region' || type == 'script') {
      assert(section.containsKey('Subtag') && section.containsKey('Description'), section.toString());
      final String subtag = section['Subtag'].single;
      String description = section['Description'].join(' ');
      if (description.startsWith('United '))
        description = 'the $description';
      if (description.contains(kParentheticalPrefix))
        description = description.substring(0, description.indexOf(kParentheticalPrefix));
      if (description.contains(kProvincePrefix))
        description = description.substring(0, description.indexOf(kProvincePrefix));
      if (description.endsWith(' Republic'))
        description = 'the $description';
      switch (type) {
        case 'language':
          _languages[subtag] = description;
          break;
        case 'region':
          _regions[subtag] = description;
          break;
        case 'script':
          _scripts[subtag] = description;
          break;
      }
    }
  }
}

String describeLocale(String tag) {
  final List<String> subtags = tag.split('_');
  assert(subtags.isNotEmpty);
  assert(_languages.containsKey(subtags[0]));
  final String language = _languages[subtags[0]];
  String output = '$language';
  String region;
  String script;
  if (subtags.length == 2) {
    region = _regions[subtags[1]];
    script = _scripts[subtags[1]];
    assert(region != null || script != null);
  } else if (subtags.length >= 3) {
    region = _regions[subtags[2]];
    script = _scripts[subtags[1]];
    assert(region != null && script != null);
  }
  if (region != null)
    output += ', as used in $region';
  if (script != null)
    output += ', using the $script script';
  return output;
}

/// Writes the header of each class which corresponds to a locale.
String generateClassDeclaration(
  LocaleInfo locale,
  String classNamePrefix,
  String superClass,
) {
  final String camelCaseName = camelCase(locale);
  return '''

/// The translations for ${describeLocale(locale.originalString)} (`${locale.originalString}`).
class $classNamePrefix$camelCaseName extends $superClass {''';
}

/// Return `s` as a Dart-parseable raw string in single or double quotes.
///
/// Double quotes are expanded:
///
/// ```
/// foo => r'foo'
/// foo "bar" => r'foo "bar"'
/// foo 'bar' => r'foo ' "'" r'bar' "'"
/// ```
String generateString(String s) {
  if (!s.contains("'"))
    return "r'$s'";

  final StringBuffer output = StringBuffer();
  bool started = false; // Have we started writing a raw string.
  for (int i = 0; i < s.length; i++) {
    if (s[i] == "'") {
      if (started)
        output.write("'");
      output.write(' "\'" ');
      started = false;
    } else if (!started) {
      output.write("r'${s[i]}");
      started = true;
    } else {
      output.write(s[i]);
    }
  }
  if (started)
    output.write("'");
  return output.toString();
}
