// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MOJO_PUBLIC_CPP_BINDINGS_MAP_H_
#define MOJO_PUBLIC_CPP_BINDINGS_MAP_H_

#include <map>

#include "mojo/public/cpp/bindings/lib/map_internal.h"

namespace mojo {

template <typename Key, typename Value>
class Map {
  MOJO_MOVE_ONLY_TYPE(Map)

 public:
  // Map keys can not be move only classes.
  static_assert(!internal::IsMoveOnlyType<Key>::value,
                "Map keys can not be move only types.");

  typedef internal::MapTraits<Key,
                              Value,
                              internal::IsMoveOnlyType<Value>::value> Traits;
  typedef typename Traits::KeyStorageType KeyStorageType;
  typedef typename Traits::KeyRefType KeyRefType;
  typedef typename Traits::KeyConstRefType KeyConstRefType;
  typedef typename Traits::KeyForwardType KeyForwardType;

  typedef typename Traits::ValueStorageType ValueStorageType;
  typedef typename Traits::ValueRefType ValueRefType;
  typedef typename Traits::ValueConstRefType ValueConstRefType;
  typedef typename Traits::ValueForwardType ValueForwardType;

  typedef internal::Map_Data<typename internal::WrapperTraits<Key>::DataType,
                             typename internal::WrapperTraits<Value>::DataType>
      Data_;

  Map() : is_null_(true) {}

  Map(mojo::Array<Key> keys, mojo::Array<Value> values) : is_null_(false) {
    MOJO_DCHECK(keys.size() == values.size());
    Traits::InitializeFrom(&map_, keys.Pass(), values.Pass());
  }

  ~Map() { Traits::Finalize(&map_); }

  Map(Map&& other) : is_null_(true) { Take(&other); }
  Map& operator=(Map&& other) {
    Take(&other);
    return *this;
  }

  template <typename U>
  static Map From(const U& other) {
    return TypeConverter<Map, U>::Convert(other);
  }

  template <typename U>
  U To() const {
    return TypeConverter<U, Map>::Convert(*this);
  }

  void reset() {
    if (!map_.empty()) {
      Traits::Finalize(&map_);
      map_.clear();
    }
    is_null_ = true;
  }

  bool is_null() const { return is_null_; }

  size_t size() const { return map_.size(); }

  // Used to mark an empty map as non-null for serialization purposes.
  void mark_non_null() { is_null_ = false; }

  // Inserts a key-value pair into the map. Like std::map, this does not insert
  // |value| if |key| is already a member of the map.
  void insert(KeyForwardType key, ValueForwardType value) {
    is_null_ = false;
    Traits::Insert(&map_, key, value);
  }

  ValueRefType at(KeyForwardType key) { return Traits::at(&map_, key); }
  ValueConstRefType at(KeyForwardType key) const {
    return Traits::at(&map_, key);
  }

  ValueRefType operator[](KeyForwardType key) {
    is_null_ = false;
    return Traits::GetOrInsert(&map_, key);
  }

  void Swap(Map<Key, Value>* other) {
    std::swap(is_null_, other->is_null_);
    map_.swap(other->map_);
  }
  void Swap(std::map<Key, Value>* other) {
    is_null_ = false;
    map_.swap(*other);
  }

  // This moves all values in the map to a set of parallel arrays. This action
  // is destructive because we can have move-only objects as values; therefore
  // we can't have copy semantics here.
  void DecomposeMapTo(mojo::Array<Key>* keys, mojo::Array<Value>* values) {
    Traits::Decompose(&map_, keys, values);
    Traits::Finalize(&map_);
    map_.clear();
    is_null_ = true;
  }

  // Please note that calling this method will fail compilation if the value
  // type cannot be cloned (which usually means that it is a Mojo handle type or
  // a type contains Mojo handles).
  Map Clone() const {
    Map result;
    result.is_null_ = is_null_;
    Traits::Clone(map_, &result.map_);
    return result.Pass();
  }

  bool Equals(const Map& other) const {
    if (is_null() != other.is_null())
      return false;
    if (size() != other.size())
      return false;
    auto i = begin();
    auto j = other.begin();
    while (i != end()) {
      if (i.GetKey() != j.GetKey())
        return false;
      if (!internal::ValueTraits<Value>::Equals(i.GetValue(), j.GetValue()))
        return false;
      ++i;
      ++j;
    }
    return true;
  }

  class ConstMapIterator {
   public:
    ConstMapIterator(
        const typename std::map<KeyStorageType,
                                ValueStorageType>::const_iterator& it)
        : it_(it) {}

    KeyConstRefType GetKey() { return Traits::GetKey(it_); }
    ValueConstRefType GetValue() { return Traits::GetValue(it_); }

    ConstMapIterator& operator++() {
      it_++;
      return *this;
    }
    bool operator!=(const ConstMapIterator& rhs) const {
      return it_ != rhs.it_;
    }
    bool operator==(const ConstMapIterator& rhs) const {
      return it_ == rhs.it_;
    }

   private:
    typename std::map<KeyStorageType, ValueStorageType>::const_iterator it_;
  };

  // Provide read-only iteration over map members.
  ConstMapIterator begin() const { return ConstMapIterator(map_.begin()); }
  ConstMapIterator end() const { return ConstMapIterator(map_.end()); }

  ConstMapIterator find(KeyForwardType key) const {
    return ConstMapIterator(map_.find(key));
  }

 private:
  typedef std::map<KeyStorageType, ValueStorageType> Map::*Testable;

 public:
  operator Testable() const { return is_null_ ? 0 : &Map::map_; }

 private:
  void Take(Map* other) {
    reset();
    Swap(other);
  }

  std::map<KeyStorageType, ValueStorageType> map_;
  bool is_null_;
};

template <typename MojoKey,
          typename MojoValue,
          typename STLKey,
          typename STLValue>
struct TypeConverter<Map<MojoKey, MojoValue>, std::map<STLKey, STLValue>> {
  static Map<MojoKey, MojoValue> Convert(
      const std::map<STLKey, STLValue>& input) {
    Map<MojoKey, MojoValue> result;
    result.mark_non_null();
    for (auto& pair : input) {
      result.insert(TypeConverter<MojoKey, STLKey>::Convert(pair.first),
                    TypeConverter<MojoValue, STLValue>::Convert(pair.second));
    }
    return result.Pass();
  }
};

template <typename MojoKey,
          typename MojoValue,
          typename STLKey,
          typename STLValue>
struct TypeConverter<std::map<STLKey, STLValue>, Map<MojoKey, MojoValue>> {
  static std::map<STLKey, STLValue> Convert(
      const Map<MojoKey, MojoValue>& input) {
    std::map<STLKey, STLValue> result;
    if (!input.is_null()) {
      for (auto it = input.begin(); it != input.end(); ++it) {
        result.insert(std::make_pair(
            TypeConverter<STLKey, MojoKey>::Convert(it.GetKey()),
            TypeConverter<STLValue, MojoValue>::Convert(it.GetValue())));
      }
    }
    return result;
  }
};

}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_MAP_H_
