// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

/// This library provides internationalization and localization. This includes
/// message formatting and replacement, date and number formatting and parsing,
/// and utilities for working with Bidirectional text.
///
/// This is part of the [intl package]
/// (https://pub.dartlang.org/packages/intl).
///
/// For things that require locale or other data, there are multiple different
/// ways of making that data available, which may require importing different
/// libraries. See the class comments for more details.
///
/// There is also a simple example application that can be found in the
/// [example/basic](https://github.com/dart-lang/intl/tree/master/example/basic)
/// directory.
library intl;

import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:math';

import 'date_symbols.dart';
import 'number_symbols.dart';
import 'number_symbols_data.dart';
import 'src/date_format_internal.dart';
import 'src/intl_helpers.dart';
import 'package:intl/src/plural_rules.dart' as plural_rules;

part 'src/intl/bidi_formatter.dart';
part 'src/intl/bidi_utils.dart';

part 'src/intl/compact_number_format.dart';
part 'src/intl/date_format.dart';
part 'src/intl/date_format_field.dart';
part 'src/intl/date_format_helpers.dart';
part 'src/intl/number_format.dart';

/// The Intl class provides a common entry point for internationalization
/// related tasks. An Intl instance can be created for a particular locale
/// and used to create a date format via `anIntl.date()`. Static methods
/// on this class are also used in message formatting.
///
/// Examples:
///      today(date) => Intl.message(
///          "Today's date is $date",
///          name: 'today',
///          args: [date],
///          desc: 'Indicate the current date',
///          examples: const {'date' : 'June 8, 2012'});
///      print(today(new DateTime.now().toString());
///
///      howManyPeople(numberOfPeople, place) => Intl.plural(numberOfPeople,
///            zero: 'I see no one at all in $place.',
///            one: 'I see $numberOfPeople other person in $place.',
///            other: 'I see $numberOfPeople other people in $place.',
///          name: 'howManyPeople',
///          args: [numberOfPeople, place],
///          desc: 'Description of how many people are seen in a place.',
///          examples: const {'numberOfPeople': 3, 'place': 'London'});
///
/// Calling `howManyPeople(2, 'Athens');` would
/// produce "I see 2 other people in Athens." as output in the default locale.
/// If run in a different locale it would produce appropriately translated
/// output.
///
/// For more detailed information on messages and localizing them see
/// the main [package documentation](https://pub.dartlang.org/packages/intl)
///
/// You can set the default locale.
///       Intl.defaultLocale = "pt_BR";
///
/// To temporarily use a locale other than the default, use the `withLocale`
/// function.
///       var todayString = new DateFormat("pt_BR").format(new DateTime.now());
///       print(withLocale("pt_BR", () => today(todayString));
///
/// See `tests/message_format_test.dart` for more examples.
//TODO(efortuna): documentation example involving the offset parameter?

class Intl {
  /// String indicating the locale code with which the message is to be
  /// formatted (such as en-CA).
  String _locale;

  /// The default locale. This defaults to being set from systemLocale, but
  /// can also be set explicitly, and will then apply to any new instances where
  /// the locale isn't specified. Note that a locale parameter to
  /// [Intl.withLocale]
  /// will supercede this value while that operation is active. Using
  /// [Intl.withLocale] may be preferable if you are using different locales
  /// in the same application.
  static String get defaultLocale {
    var zoneLocale = Zone.current[#Intl.locale];
    return zoneLocale == null ? _defaultLocale : zoneLocale;
  }

  static set defaultLocale(String newLocale) {
    _defaultLocale = newLocale;
  }

  static String _defaultLocale;

  /// The system's locale, as obtained from the window.navigator.language
  /// or other operating system mechanism. Note that due to system limitations
  /// this is not automatically set, and must be set by importing one of
  /// intl_browser.dart or intl_standalone.dart and calling findSystemLocale().
  static String systemLocale = 'en_US';

  /// Return a new date format using the specified [pattern].
  /// If [desiredLocale] is not specified, then we default to [locale].
  DateFormat date([String pattern, String desiredLocale]) {
    var actualLocale = (desiredLocale == null) ? locale : desiredLocale;
    return new DateFormat(pattern, actualLocale);
  }

  /// Constructor optionally [aLocale] for specifics of the language
  /// locale to be used, otherwise, we will attempt to infer it (acceptable if
  /// Dart is running on the client, we can infer from the browser/client
  /// preferences).
  Intl([String aLocale]) {
    _locale = aLocale != null ? aLocale : getCurrentLocale();
  }

  /// Use this for a message that will be translated for different locales. The
  /// expected usage is that this is inside an enclosing function that only
  /// returns the value of this call and provides a scope for the variables that
  /// will be substituted in the message.
  ///
  /// The [message_str] is the string to be translated, which may be
  /// interpolated based on one or more variables.
  ///
  /// The [args] is a list containing the arguments of the enclosing function.
  /// If there are no arguments, [args] can be omitted.
  ///
  /// The [name] is required only for messages that have [args], and optional
  /// for messages without [args]. It is used at runtime to look up the message
  /// and pass the appropriate arguments to it. If provided, [name] must be
  /// globally unique in the program. It must match the enclosing function name,
  /// or if the function is a method of a class, [name] can also be of the form
  /// <className>_<methodName>, to make it easier to distinguish messages with
  /// the same name but in different classes.
  ///
  /// The [desc] provides a description of the message usage.
  ///
  /// The [examples] is a const Map of examples for each interpolated variable.
  /// For example
  ///
  ///       hello(yourName) => Intl.message(
  ///         "Hello, $yourName",
  ///         name: "hello",
  ///         args: [yourName],
  ///         desc: "Say hello",
  ///         examples: const {"yourName": "Sparky"});
  ///
  /// The source code will be processed via the analyzer to extract out the
  /// message data, so only a subset of valid Dart code is accepted. In
  /// particular, everything must be literal and cannot refer to variables
  /// outside the scope of the enclosing function. The [examples] map must be a
  /// valid const literal map. Similarly, the [desc] argument must be a single,
  /// simple string and [skip] a boolean literal. These three arguments will not
  /// be used at runtime but will be extracted from the source code and used as
  /// additional data for translators. For more information see the "Messages"
  /// section of the main
  /// [package documentation] (https://pub.dartlang.org/packages/intl).
  ///
  /// The [skip] arg will still validate the message, but will be filtered from
  /// the extracted message output. This can be useful to set up placeholder
  /// messages during development whose text aren't finalized yet without having
  /// the placeholder automatically translated.
  static String message(String message_str,
          {String desc: '',
          Map<String, Object> examples,
          String locale,
          String name,
          List<Object> args,
          String meaning,
          bool skip}) =>
      _message(message_str, locale, name, args, meaning);

  /// Omit the compile-time only parameters so dart2js can see to drop them.
  static String _message(String message_str, String locale, String name,
      List<Object> args, String meaning) {
    return messageLookup.lookupMessage(
        message_str, locale, name, args, meaning);
  }

  /// Return the locale for this instance. If none was set, the locale will
  /// be the default.
  String get locale => _locale;

  /// Given [newLocale] return a locale that we have data for that is similar
  /// to it, if possible.
  ///
  /// If [newLocale] is found directly, return it. If it can't be found, look up
  /// based on just the language (e.g. 'en_CA' -> 'en'). Also accepts '-'
  /// as a separator and changes it into '_' for lookup, and changes the
  /// country to uppercase.
  ///
  /// There is a special case that if a locale named "fallback" is present
  /// and has been initialized, this will return that name. This can be useful
  /// for messages where you don't want to just use the text from the original
  /// source code, but wish to have a universal fallback translation.
  ///
  /// Note that null is interpreted as meaning the default locale, so if
  /// [newLocale] is null the default locale will be returned.
  static String verifiedLocale(String newLocale, Function localeExists,
      {Function onFailure: _throwLocaleError}) {
    // TODO(alanknight): Previously we kept a single verified locale on the Intl
    // object, but with different verification for different uses, that's more
    // difficult. As a result, we call this more often. Consider keeping
    // verified locales for each purpose if it turns out to be a performance
    // issue.
    if (newLocale == null) {
      return verifiedLocale(getCurrentLocale(), localeExists,
          onFailure: onFailure);
    }
    if (localeExists(newLocale)) {
      return newLocale;
    }
    for (var each in [
      canonicalizedLocale(newLocale),
      shortLocale(newLocale),
      "fallback"
    ]) {
      if (localeExists(each)) {
        return each;
      }
    }
    return onFailure(newLocale);
  }

  /// The default action if a locale isn't found in verifiedLocale. Throw
  /// an exception indicating the locale isn't correct.
  static String _throwLocaleError(String localeName) {
    throw new ArgumentError("Invalid locale '$localeName'");
  }

  /// Return the short version of a locale name, e.g. 'en_US' => 'en'
  static String shortLocale(String aLocale) {
    if (aLocale.length < 2) return aLocale;
    return aLocale.substring(0, 2).toLowerCase();
  }

  /// Return the name [aLocale] turned into xx_YY where it might possibly be
  /// in the wrong case or with a hyphen instead of an underscore. If
  /// [aLocale] is null, for example, if you tried to get it from IE,
  /// return the current system locale.
  static String canonicalizedLocale(String aLocale) {
    // Locales of length < 5 are presumably two-letter forms, or else malformed.
    // We return them unmodified and if correct they will be found.
    // Locales longer than 6 might be malformed, but also do occur. Do as
    // little as possible to them, but make the '-' be an '_' if it's there.
    // We treat C as a special case, and assume it wants en_ISO for formatting.
    // TODO(alanknight): en_ISO is probably not quite right for the C/Posix
    // locale for formatting. Consider adding C to the formats database.
    if (aLocale == null) return getCurrentLocale();
    if (aLocale == "C") return "en_ISO";
    if (aLocale.length < 5) return aLocale;
    if (aLocale[2] != '-' && (aLocale[2] != '_')) return aLocale;
    var region = aLocale.substring(3);
    // If it's longer than three it's something odd, so don't touch it.
    if (region.length <= 3) region = region.toUpperCase();
    return '${aLocale[0]}${aLocale[1]}_$region';
  }

  /// Formats a message differently depending on [howMany].
  ///
  /// Selects the correct plural form from the provided alternatives.
  /// The [other] named argument is mandatory.
  /// The [precision] is the number of fractional digits that would be rendered
  /// when [howMany] is formatted. In some cases just knowing the numeric value
  /// of [howMany] itsef is not enough, for example "1 mile" vs "1.00 miles"
  ///
  /// For an explanation of plurals and the [zero], [one], [two], [few], [many]
  /// categories see http://cldr.unicode.org/index/cldr-spec/plural-rules
  static String plural(num howMany,
      {String zero,
      String one,
      String two,
      String few,
      String many,
      String other,
      String desc,
      Map<String, Object> examples,
      String locale,
      int precision,
      String name,
      List<Object> args,
      String meaning,
      bool skip}) {
    // Call our internal method, dropping examples and desc because they're not
    // used at runtime and we want them to be optimized away.
    return _plural(howMany,
        zero: zero,
        one: one,
        two: two,
        few: few,
        many: many,
        other: other,
        locale: locale,
        precision: precision,
        name: name,
        args: args,
        meaning: meaning);
  }

  static String _plural(num howMany,
      {String zero,
      String one,
      String two,
      String few,
      String many,
      String other,
      String locale,
      int precision,
      String name,
      List<Object> args,
      String meaning}) {
    // Look up our translation, but pass in a null message so we don't have to
    // eagerly evaluate calls that may not be necessary.
    var translated = _message(null, locale, name, args, meaning);

    /// If there's a translation, return it, otherwise evaluate with our
    /// original text.
    return translated ??
        pluralLogic(howMany,
            zero: zero,
            one: one,
            two: two,
            few: few,
            many: many,
            other: other,
            locale: locale,
            precision: precision);
  }

  /// Internal: Implements the logic for plural selection - use [plural] for
  /// normal messages.
  static pluralLogic(num howMany,
      {zero, one, two, few, many, other, String locale, int precision,
      String meaning}) {
    if (other == null) {
      throw new ArgumentError("The 'other' named argument must be provided");
    }
    if (howMany == null) {
      throw new ArgumentError("The howMany argument to plural cannot be null");
    }

    // This is for backward compatibility.
    // We interpret the presence of [precision] parameter as an "opt-in" to
    // the new behavior, since [precision] did not exist before.
    // For an English example: if the precision is 2 then the formatted string
    // would not map to 'one' (for example "1.00 miles")
    if (precision == null || precision == 0) {
      // If there's an explicit case for the exact number, we use it. This is
      // not strictly in accord with the CLDR rules, but it seems to be the
      // expectation. At least I see e.g. Russian translations that have a zero
      // case defined. The rule for that locale will never produce a zero, and
      // treats it as other. But it seems reasonable that, even if the language
      // rules treat zero as other, we might want a special message for zero.
      if (howMany == 0 && zero != null) return zero;
      if (howMany == 1 && one != null) return one;
      if (howMany == 2 && two != null) return two;
    }

    var pluralRule = _pluralRule(locale, howMany, precision);
    var pluralCase = pluralRule();
    switch (pluralCase) {
      case plural_rules.PluralCase.ZERO:
        return zero ?? other;
      case plural_rules.PluralCase.ONE:
        return one ?? other;
      case plural_rules.PluralCase.TWO:
        return two ?? few ?? other;
      case plural_rules.PluralCase.FEW:
        return few ?? other;
      case plural_rules.PluralCase.MANY:
        return many ?? other;
      case plural_rules.PluralCase.OTHER:
        return other;
      default:
        throw new ArgumentError.value(
            howMany, "howMany", "Invalid plural argument");
    }
  }

  static var _cachedPluralRule;
  static String _cachedPluralLocale;

  static _pluralRule(String locale, num howMany, int precision) {
    plural_rules.startRuleEvaluation(howMany, precision);
    var verifiedLocale = Intl.verifiedLocale(
        locale, plural_rules.localeHasPluralRules,
        onFailure: (locale) => 'default');
    if (_cachedPluralLocale == verifiedLocale) {
      return _cachedPluralRule;
    } else {
      _cachedPluralRule = plural_rules.pluralRules[verifiedLocale];
      _cachedPluralLocale = verifiedLocale;
      return _cachedPluralRule;
    }
  }

  /// Format a message differently depending on [targetGender].
  static String gender(String targetGender,
      {String female,
      String male,
      String other,
      String desc,
      Map<String, Object> examples,
      String locale,
      String name,
      List<Object> args,
      String meaning,
      bool skip}) {
    // Call our internal method, dropping args and desc because they're not used
    // at runtime and we want them to be optimized away.
    return _gender(targetGender,
        male: male,
        female: female,
        other: other,
        locale: locale,
        name: name,
        args: args,
        meaning: meaning);
  }

  static String _gender(String targetGender,
      {String female,
      String male,
      String other,
      String desc,
      String locale,
      String name,
      List<Object> args,
      String meaning}) {
    // Look up our translation, but pass in a null message so we don't have to
    // eagerly evaluate calls that may not be necessary.
    var translated = _message(null, locale, name, args, meaning);

    /// If there's a translation, return it, otherwise evaluate with our
    /// original text.
    return translated ??
        genderLogic(targetGender,
            female: female, male: male, other: other, locale: locale);
  }

  /// Internal: Implements the logic for gender selection - use [gender] for
  /// normal messages.
  static genderLogic(String targetGender,
      {female, male, other, String locale}) {
    if (other == null) {
      throw new ArgumentError("The 'other' named argument must be specified");
    }
    switch (targetGender) {
      case "female":
        return female == null ? other : female;
      case "male":
        return male == null ? other : male;
      default:
        return other;
    }
  }

  /// Format a message differently depending on [choice].
  ///
  /// We look up the value
  /// of [choice] in [cases] and return the result, or an empty string if
  /// it is not found. Normally used as part
  /// of an Intl.message message that is to be translated.
  ///
  /// It is possible to use a Dart enum as the choice and as the
  /// key in cases, but note that we will process this by truncating
  /// toString() of the enum and using just the name part. We will
  /// do this for any class or strings that are passed, since we
  /// can't actually identify if something is an enum or not.
  ///
  /// The first argument in [args] must correspond to the [choice] Object.
  static String select(Object choice, Map<Object, String> cases,
      {String desc,
      Map<String, Object> examples,
      String locale,
      String name,
      List<Object> args,
      String meaning,
      bool skip}) {
    return _select(choice, cases,
        locale: locale, name: name, args: args, meaning: meaning);
  }

  static String _select(Object choice, Map<Object, String> cases,
      {String locale, String name, List<Object> args, String meaning}) {
    // Look up our translation, but pass in a null message so we don't have to
    // eagerly evaluate calls that may not be necessary.
    var stringChoice = choice is String ? choice : "$choice".split('.').last;
    var modifiedArgs =
        args == null ? null : (<Object>[stringChoice]..addAll(args.skip(1)));
    var translated = _message(null, locale, name, modifiedArgs, meaning);

    /// If there's a translation, return it, otherwise evaluate with our
    /// original text.
    return translated ?? selectLogic(choice, cases);
  }

  /// Internal: Implements the logic for select - use [select] for
  /// normal messages.
  static selectLogic(Object choice, Map<Object, dynamic> cases) {
    // This will work if choice is a string, or if it's e.g. an
    // enum and the map uses the enum values as choices.
    var exact = cases[choice];
    if (exact != null) return exact;
    // If it didn't match exactly, take the toString and
    // take the part after the period. We need to do this
    // because enums print as 'EnumType.enumName' and periods
    // aren't acceptable in ICU select choices.
    var stringChoice = "$choice".split('.').last;
    var stringMatch = cases[stringChoice];
    if (stringMatch != null) return stringMatch;
    var other = cases["other"];
    if (other == null)
      throw new ArgumentError("The 'other' case must be specified");
    return other;
  }

  /// Run [function] with the default locale set to [locale] and
  /// return the result.
  ///
  /// This is run in a zone, so async operations invoked
  /// from within [function] will still have the locale set.
  ///
  /// In simple usage [function] might be a single
  /// `Intl.message()` call or number/date formatting operation. But it can
  /// also be an arbitrary function that calls multiple Intl operations.
  ///
  /// For example
  ///
  ///       Intl.withLocale("fr", () => new NumberFormat.format(123456));
  ///
  /// or
  ///
  ///       hello(name) => Intl.message(
  ///           "Hello $name.",
  ///           name: 'hello',
  ///           args: [name],
  ///           desc: 'Say Hello');
  ///       Intl.withLocale("zh", new Timer(new Duration(milliseconds:10),
  ///           () => print(hello("World")));
  static withLocale(String locale, function()) {
    var canonical = Intl.canonicalizedLocale(locale);
    return runZoned(function, zoneValues: {#Intl.locale: canonical});
  }

  /// Accessor for the current locale. This should always == the default locale,
  /// unless for some reason this gets called inside a message that resets the
  /// locale.
  static String getCurrentLocale() {
    if (defaultLocale == null) defaultLocale = systemLocale;
    return defaultLocale;
  }

  toString() => "Intl($locale)";
}

/// Convert a string to beginning of sentence case, in a way appropriate to the
/// locale.
///
/// Currently this just converts the first letter to uppercase, which works for
/// many locales, and we have the option to extend this to handle more cases
/// without changing the API for clients. It also hard-codes the case of
/// dotted i in Turkish and Azeri.
String toBeginningOfSentenceCase(String input, [String locale]) {
  if (input == null || input.isEmpty) return input;
  return "${_upperCaseLetter(input[0], locale)}${input.substring(1)}";
}

/// Convert the input single-letter string to upper case. A trivial
/// hard-coded implementation that only handles simple upper case
/// and the dotted i in Turkish/Azeri.
///
/// Private to the implementation of [toBeginningOfSentenceCase].
// TODO(alanknight): Consider hard-coding other important cases.
// See http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt
// TODO(alanknight): Alternatively, consider toLocaleUpperCase in browsers.
// See also https://github.com/dart-lang/sdk/issues/6706
String _upperCaseLetter(String input, String locale) {
  // Hard-code the important edge case of i->İ
  if (locale != null) {
    if (input == "i" && locale.startsWith("tr") || locale.startsWith("az")) {
      return "\u0130";
    }
  }
  return input.toUpperCase();
}
