// Copyright (c) 2016, 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.

library observable.src.to_observable;

import 'dart:collection';

import 'package:dart_internal/extract_type_arguments.dart';

import 'observable.dart' show Observable;
import 'observable_list.dart' show ObservableList;
import 'observable_map.dart' show ObservableMap;

/// Converts the [Iterable] or [Map] to an [ObservableList] or [ObservableMap],
/// respectively. This is a convenience function to make it easier to convert
/// literals into the corresponding observable collection type.
///
/// For better static typing, use either [toObservableList] or
/// [toObservableMap] instead of this function.
///
/// If [value] is not one of those collection types, or is already [Observable],
/// it will be returned unmodified.
///
/// If [value] is a [Map], the resulting value will use the appropriate kind of
/// backing map: either [HashMap], [LinkedHashMap], or [SplayTreeMap].
///
/// By default this performs a deep conversion, but you can set [deep] to false
/// for a shallow conversion. This does not handle circular data structures.
/// If a conversion is peformed, mutations are only observed to the result of
/// this function. Changing the original collection will not affect it.
// TODO(jmesserly): ObservableSet?
dynamic toObservable(dynamic value, {bool deep = true}) =>
    deep ? _toObservableDeep(value) : _toObservableShallow(value);

/// Converts the [Iterable] to an [ObservableList].
///
/// If [value] is already [Observable], it will be returned unmodified.
///
/// By default this performs a deep conversion, but you can set [deep] to false
/// for a shallow conversion. This does not handle circular data structures.
/// If a conversion is peformed, mutations are only observed to the result of
/// this function. Changing the original collection will not affect it.
ObservableList<T> toObservableList<T>(Iterable<T> value, {bool deep = true}) {
  if (value is ObservableList<T>) return value;
  return deep
      ? _toObservableDeepIterable(value) as ObservableList<T>
      : _toObservableShallow(value);
}

/// Converts the [Map] to an [ObservableMap].
///
/// If [value] is already [Observable], it will be returned unmodified.
///
/// The returned value will use the appropriate kind of backing map: either
/// [HashMap], [LinkedHashMap], or [SplayTreeMap].
///
/// By default this performs a deep conversion, but you can set [deep] to false
/// for a shallow conversion. This does not handle circular data structures.
/// If a conversion is peformed, mutations are only observed to the result of
/// this function. Changing the original collection will not affect it.
ObservableMap<K, V> toObservableMap<K, V>(Map<K, V> value, {bool deep = true}) {
  if (value is ObservableMap<K, V>) return value;
  return deep
      ? _toObservableDeepMap(value) as ObservableMap<K, V>
      : _toObservableShallow(value);
}

dynamic _toObservableShallow(dynamic value) {
  if (value is Observable) return value;

  if (value is Map) {
    return extractMapTypeArguments(
        value, <K, V>() => ObservableMap<K, V>.from(value.cast<K, V>()));
  }

  if (value is Iterable) {
    return extractIterableTypeArgument(
        value, <T>() => ObservableList<T>.from(value.cast<T>()));
  }

  return value;
}

dynamic _toObservableDeep(dynamic value) {
  if (value is Observable) return value;

  if (value is Map) return _toObservableDeepMap(value);

  if (value is Iterable) return _toObservableDeepIterable(value);

  return value;
}

ObservableMap _toObservableDeepMap(Map<dynamic, dynamic> value) {
  return extractMapTypeArguments(value, <K, V>() {
    var result = ObservableMap<K, V>.createFromType(value.cast<K, V>());
    value.forEach((k, v) {
      result[_toObservableDeep(k)] = _toObservableDeep(v);
    });
    return result;
  }) as ObservableMap<dynamic, dynamic>;
}

ObservableList _toObservableDeepIterable(Iterable<dynamic> value) {
  return extractIterableTypeArgument(value, <T>() {
    var result = ObservableList<T>();
    for (var element in value) {
      result.add(_toObservableDeep(element));
    }
    return result;
  }) as ObservableList<dynamic>;
}
