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

/**
 * Message/plural format library with locale support. This can have different
 * implementations based on the mechanism for finding the localized versions
 * of messages. This version expects them to be in a library named e.g.
 * 'messages_en_US'. The prefix is set in the [initializeMessages] call, which
 * must be made for a locale before any lookups can be done.
 *
 * See Intl class comment or `tests/message_format_test.dart` for more examples.
 */
library message_lookup_by_library;

import 'dart:async';
import 'intl.dart';
import 'src/intl_helpers.dart';

/**
 * This is a message lookup mechanism that delegates to one of a collection
 * of individual [MessageLookupByLibrary] instances.
 */
class CompositeMessageLookup {
  /** A map from locale names to the corresponding lookups. */
  Map<String, MessageLookupByLibrary> availableMessages = new Map();

  /** Return true if we have a message lookup for [localeName]. */
  bool localeExists(localeName) => availableMessages.containsKey(localeName);

  /**
   * Look up the message with the given [name] and [locale] and return
   * the translated version with the values in [args] interpolated.
   * If nothing is found, return [message_str]. The [desc] and [examples]
   * parameters are ignored
   */
  String lookupMessage(String message_str, [final String desc='',
      final Map examples=const {}, String locale,
      String name, List<String> args]) {
    var actualLocale = (locale == null) ? Intl.getCurrentLocale() : locale;
      // For this usage, if the locale doesn't exist for messages, just return
      // it and we'll fall back to the original version.
    var verifiedLocale =
        Intl.verifiedLocale(
            actualLocale,
            localeExists,
            onFailure: (locale)=>locale);
    var messages = availableMessages[verifiedLocale];
    if (messages == null) return message_str;
    return messages.
        lookupMessage(message_str, desc, examples, locale, name, args);
  }

  /**
   * If we do not already have a locale for [localeName] then
   * [findLocale] will be called and the result stored as the lookup
   * mechanism for that locale.
   */
  addLocale(String localeName, Function findLocale) {
    if (localeExists(localeName)) return;
    var newLocale = findLocale(localeName);
    if (newLocale != null) {
      availableMessages[localeName] = newLocale;
    }
  }
}

/**
 * This provides an abstract class for messages looked up in generated code.
 * Each locale will have a separate subclass of this class with its set of
 * messages. See generate_localized.dart.
 */
abstract class MessageLookupByLibrary {
  /** Prevent infinite recursion when looking up the message. */
  bool _lookupInProgress = false;

  /**
   * Return true if the locale exists, or if it is null. Null is treated
   * as meaning that we use the default locale.
   */
  bool localeExists(localeName);

  /**
   * Return the localized version of a message. We are passed the original
   * version of the message, which consists of a
   * [message_str] that will be translated, and which may be interpolated
   * based on one or more variables, a [desc] providing a description of usage
   * for the [message_str], and a map of [examples] for each data element to be
   * substituted into the message.
   *
   * For example, if message="Hello, $name", then
   * examples = {'name': 'Sparky'}. If not using the user's default locale, or
   * if the locale is not easily detectable, explicitly pass [locale].
   *
   * The values of [desc] and [examples] are not used at run-time but are only
   * made available to the translators, so they MUST be simple Strings available
   * at compile time: no String interpolation or concatenation.
   * The expected usage of this is inside a function that takes as parameters
   * the variables used in the interpolated string.
   *
   * Ultimately, the information about the enclosing function and its arguments
   * will be extracted automatically but for the time being it must be passed
   * explicitly in the [name] and [args] arguments.
   */
  String lookupMessage(String message_str, [final String desc='',
      final Map examples=const {}, String locale,
      String name, List<String> args]) {
    // If we don't have a name, return the original, and if we have
    // been recursively invoked, also just return message_str. This
    // happens because the replacement functions also call Intl.message,
    // so we assume that when _lookupInProgress is true that we're
    // already translated.
    if (name == null || _lookupInProgress) return message_str;
    _lookupInProgress = true;
    // Try to apply the function holding the translated version. If there
    // is an exception, use the original [message_str] as the result.
    var result = message_str;
    try {
      var function = this[name];
      if (function != null) result = Function.apply(function, args);
    } finally {
      _lookupInProgress = false;
    }
    return result;
  }

  /** Return our message with the given name */
  operator [](String messageName) => messages[messageName];

  /**
   * Subclasses should override this to return a list of their message
   * functions.
   */
  Map<String, Function> get messages;

  /** Subclasses should override this to return their locale, e.g. 'en_US' */
  String get localeName;

  toString() => localeName;
}