// 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 defines a class for loading locale data incrementally from
 * an external source as JSON. The external sources expected are either
 * local files or via HTTP request.
 */

library lazy_locale_data;

import 'dart:async';
import 'dart:convert';
import 'intl_helpers.dart';

/**
 * This implements the very basic map-type operations which are used
 * in locale lookup, and looks them up based on a URL that defines
 * the external source.
 */
class LazyLocaleData {
  /// This holds the data we have loaded.
  Map map;

  /// The object that actually does the data reading.
  LocaleDataReader _reader;

  /**
   * In order to avoid a potentially remote call to see if a locale
   * is available, we hold a complete list of all the available
   * locales.
   */
  List availableLocales;

  /**
   * Given a piece of remote data, apply [_creationFunction] to it to
   * convert it into the right form. Typically this means converting it
   * from a Map into an object form.
   */
  Function _creationFunction;

  /**
   * The set of available locales.
   */
  Set availableLocaleSet;

  /**
   * The constructor. The [_reader] specifies where the data comes
   * from. The [_creationFunction] creates the appropriate data type
   * from the remote data (which typically comes in as a Map). The
   * [keys] lists the set of remotely available locale names so we know which
   * things can be fetched without having to check remotely.
   */
  LazyLocaleData(this._reader, this._creationFunction, List keys) {
    map = new Map();
    availableLocales = keys;
    availableLocaleSet = new Set.from(availableLocales);
  }

  /**
   *  Tests if we have data for the locale available. Note that this returns
   * true even if the data is known to be available remotely but not yet loaded.
   */
  bool containsKey(String locale) => availableLocaleSet.contains(locale);

  /** Returns the list of keys/locale names. */
  List get keys => availableLocales;

  /**
   * Returns the data stored for [localeName]. If no data has been loaded
   * for [localeName], throws an exception. If no data is available for
   * [localeName] then throw an exception with a different message.
   */
  operator [](String localeName) {
    if (containsKey(localeName)) {
      var data = map[localeName];
      if (data == null) {
        throw new LocaleDataException(
            "Locale $localeName has not been initialized."
            " Call initializeDateFormatting($localeName, <data url>) first");
      } else {
        return data;
      }
    } else {
      unsupportedLocale(localeName);
    }
  }

  /**
   * Throw an exception indicating that the locale has no data available,
   * either locally or remotely.
   */
  unsupportedLocale(localeName) {
    throw new LocaleDataException('Locale $localeName has no data available');
  }

  /**
   * Initialize for locale. Internal use only. As a user, call
   * initializeDateFormatting instead.
   */
  Future initLocale(String localeName) {
    var data = _reader.read(localeName);
    return jsonData(data).then((input) {
      map[localeName] = _creationFunction(input);
    });
  }

  /**
   * Given a Future [input] whose value is expected to be a string in JSON form,
   * return another future that parses the JSON into a usable format.
   */
  Future jsonData(Future input) {
    return input.then((response) => JSON.decode(response));
  }
}
