// 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_LIB_MAP_SERIALIZATION_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_

#include <type_traits>

#include "mojo/public/cpp/bindings/lib/array_internal.h"
#include "mojo/public/cpp/bindings/lib/array_serialization.h"
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/lib/iterator_util.h"
#include "mojo/public/cpp/bindings/lib/map_data_internal.h"
#include "mojo/public/cpp/bindings/lib/map_internal.h"
#include "mojo/public/cpp/bindings/lib/string_serialization.h"
#include "mojo/public/cpp/bindings/lib/template_util.h"
#include "mojo/public/cpp/bindings/map.h"

namespace mojo {
namespace internal {

template <typename MapType,
          typename DataType,
          bool value_is_move_only_type = IsMoveOnlyType<MapType>::value,
          bool is_union = IsUnionDataType<
              typename std::remove_pointer<DataType>::type>::value>
struct MapSerializer;

template <typename MapType, typename DataType>
struct MapSerializer<MapType, DataType, false, false> {
  static size_t GetBaseArraySize(size_t count) {
    return Align(count * sizeof(DataType));
  }
  static size_t GetItemSize(const MapType& item) { return 0; }
};

template <>
struct MapSerializer<bool, bool, false, false> {
  static size_t GetBaseArraySize(size_t count) {
    return Align((count + 7) / 8);
  }
  static size_t GetItemSize(bool item) { return 0; }
};

template <typename H>
struct MapSerializer<ScopedHandleBase<H>, H, true, false> {
  static size_t GetBaseArraySize(size_t count) {
    return Align(count * sizeof(H));
  }
  static size_t GetItemSize(const ScopedHandleBase<H>& item) { return 0; }
};

// This template must only apply to pointer mojo entity (structs and arrays).
// This is done by ensuring that WrapperTraits<S>::DataType is a pointer.
template <typename S>
struct MapSerializer<
    S,
    typename std::enable_if<
        std::is_pointer<typename WrapperTraits<S>::DataType>::value,
        typename WrapperTraits<S>::DataType>::type,
    true,
    false> {
  typedef
      typename std::remove_pointer<typename WrapperTraits<S>::DataType>::type
          S_Data;
  static size_t GetBaseArraySize(size_t count) {
    return count * sizeof(StructPointer<S_Data>);
  }
  static size_t GetItemSize(const S& item) {
    return item ? GetSerializedSize_(*UnwrapConstStructPtr<S>::value(item)) : 0;
  }
};

template <typename U, typename U_Data>
struct MapSerializer<U, U_Data, true, true> {
  static size_t GetBaseArraySize(size_t count) {
    return count * sizeof(U_Data);
  }
  static size_t GetItemSize(const U& item) {
    return GetSerializedSize_(item, true);
  }
};

template <>
struct MapSerializer<String, String_Data*, false, false> {
  static size_t GetBaseArraySize(size_t count) {
    return count * sizeof(StringPointer);
  }
  static size_t GetItemSize(const String& item) {
    return GetSerializedSize_(item);
  }
};

}  // namespace internal

// TODO(erg): This can't go away yet. We still need to calculate out the size
// of a struct header, and two arrays.
template <typename MapKey, typename MapValue>
inline size_t GetSerializedSize_(const Map<MapKey, MapValue>& input) {
  if (!input)
    return 0;
  typedef typename internal::WrapperTraits<MapKey>::DataType DataKey;
  typedef typename internal::WrapperTraits<MapValue>::DataType DataValue;

  size_t count = input.size();
  size_t struct_overhead = sizeof(mojo::internal::Map_Data<DataKey, DataValue>);
  size_t key_base_size =
      sizeof(internal::ArrayHeader) +
      internal::MapSerializer<MapKey, DataKey>::GetBaseArraySize(count);
  size_t value_base_size =
      sizeof(internal::ArrayHeader) +
      internal::MapSerializer<MapValue, DataValue>::GetBaseArraySize(count);

  size_t key_data_size = 0;
  size_t value_data_size = 0;
  for (auto it = input.cbegin(); it != input.cend(); ++it) {
    key_data_size +=
        internal::MapSerializer<MapKey, DataKey>::GetItemSize(it.GetKey());
    value_data_size +=
        internal::MapSerializer<MapValue, DataValue>::GetItemSize(
            it.GetValue());
  }

  return struct_overhead + key_base_size + key_data_size + value_base_size +
         value_data_size;
}

// SerializeMap_ will return ValidationError::NONE on success and set
// |output| accordingly.  On failure, |input| will be partially serialized into
// |output| up until an error occurs (which is propagated up and returned by
// SerializeMap_), in which case |buf| is also partially consumed.
//
// We don't need an ArrayValidateParams instance for key validation since
// we can deduce it from the Key type. (which can only be primitive types or
// non-nullable strings.)
template <typename MapKey,
          typename MapValue,
          typename DataKey,
          typename DataValue>
inline internal::ValidationError SerializeMap_(
    Map<MapKey, MapValue>* input,
    internal::Buffer* buf,
    internal::Map_Data<DataKey, DataValue>** output,
    const internal::ArrayValidateParams* value_validate_params) {
  if (input->is_null()) {
    // |input| could be a nullable map, in which case |output| is serialized as
    // null, which is valid.
    *output = nullptr;
    return internal::ValidationError::NONE;
  }

  internal::Map_Data<DataKey, DataValue>* result =
      internal::Map_Data<DataKey, DataValue>::New(buf);

  // We *must* serialize the keys before we allocate an Array_Data for the
  // values.
  internal::Array_Data<DataKey>* keys_data =
      internal::Array_Data<DataKey>::New(input->size(), buf);
  result->keys.ptr = keys_data;

  internal::MapKeyIterator<MapKey, MapValue> key_iter(input);
  const internal::ArrayValidateParams* key_validate_params =
      internal::MapKeyValidateParamsFactory<DataKey>::Get();

  auto keys_retval =
      internal::ArraySerializer<MapKey, DataKey>::SerializeElements(
          key_iter.begin(), input->size(), buf, result->keys.ptr,
          key_validate_params);
  if (keys_retval != internal::ValidationError::NONE)
    return keys_retval;

  // Now we try allocate an Array_Data for the values
  internal::Array_Data<DataValue>* values_data =
      internal::Array_Data<DataValue>::New(input->size(), buf);
  result->values.ptr = values_data;

  internal::MapValueIterator<MapKey, MapValue> value_iter(input);

  auto values_retval =
      internal::ArraySerializer<MapValue, DataValue>::SerializeElements(
          value_iter.begin(), input->size(), buf, result->values.ptr,
          value_validate_params);
  if (values_retval != internal::ValidationError::NONE)
    return values_retval;

  *output = result;
  return internal::ValidationError::NONE;
}

template <typename MapKey,
          typename MapValue,
          typename DataKey,
          typename DataValue>
inline void Deserialize_(internal::Map_Data<DataKey, DataValue>* input,
                         Map<MapKey, MapValue>* output) {
  if (input) {
    Array<MapKey> keys;
    Array<MapValue> values;

    Deserialize_(input->keys.ptr, &keys);
    Deserialize_(input->values.ptr, &values);

    *output = Map<MapKey, MapValue>(keys.Pass(), values.Pass());
  } else {
    output->reset();
  }
}

}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_MAP_SERIALIZATION_H_
