// 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<dynamic, dynamic> map;

  /// The object that actually does the data reading.
  final 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<String> 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.
  final Function _creationFunction;

  /// The set of available locales.
  Set<String> 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, this.availableLocales) {
    map = Map();
    availableLocaleSet = 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<String> 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.
  dynamic operator [](String localeName) {
    if (containsKey(localeName)) {
      var data = map[localeName];
      if (data == null) {
        throw 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.
  void unsupportedLocale(localeName) {
    throw LocaleDataException('Locale $localeName has no data available');
  }

  /// Initialize for locale. Internal use only. As a user, call
  /// initializeDateFormatting instead.
  Future<void> 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<dynamic> jsonData(Future<String> input) {
    return input.then((response) => json.decode(response));
  }
}
