// 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.

// TODO(vardhan):  Currently, the logic for serializing a mojom type exists in
// two places: the C++ code generator template, and here.  However, most types
// are serialized the same way within Arrays or outside, with the exception of
// |bool|.  Consider defining serialization/deserialization traits for each
// serializable type and call those traits from here.  This should help us
// remove most of the ArraySerializer<> specializations here.

#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
#define MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_

#include <string.h>  // For |memcpy()|.
#include <type_traits>
#include <vector>

#include "mojo/public/c/system/macros.h"
#include "mojo/public/cpp/bindings/lib/array_internal.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_serialization_forward.h"
#include "mojo/public/cpp/bindings/lib/string_serialization.h"
#include "mojo/public/cpp/bindings/lib/validation_errors.h"

namespace mojo {

template <typename Interface>
InterfaceRequest<Interface> MakeRequest(ScopedMessagePipeHandle handle);

namespace internal {

// The ArraySerializer template contains static methods for serializing |Array|s
// of various types.  These methods include:
//   * size_t GetSerializedSize(..)
//       Computes the size of the serialized version of the |Array|.
//   * void SerializeElements(..)
//       Takes an |Iterator| and a size and serializes it.
//   * void DeserializeElements(..)
//       Takes a pointer to an |Array_Data| and deserializes it into a given
//       |Array|.
//
// Note: The enable template parameter exists only to allow partial
// specializations to disable instantiation using logic based on E and F.
// By default, assuming that there are no other substitution failures, the
// specialization will instantiate and needs to take no action.  A partial
// specialization of the form
//
// template<E, F> struct ArraySerialzer<E, F>
//
// may be limited to values of E and F with particular properties by supplying
// an expression for enable which will cause substitution failure if the
// properties of E and F do not satisfy the expression.
template <typename E,
          typename F,
          bool is_union =
              IsUnionDataType<typename std::remove_pointer<F>::type>::value,
          typename enable = void>
struct ArraySerializer;

// Handles serialization and deserialization of arrays of pod types.
template <typename E, typename F>
struct ArraySerializer<
    E,
    F,
    false,
    typename std::enable_if<std::is_convertible<E, F>::value ||
                                (std::is_enum<E>::value &&
                                 std::is_same<F, int32_t>::value),
                            void>::type> {
  static_assert(sizeof(E) == sizeof(F), "Incorrect array serializer");
  static size_t GetSerializedSize(const Array<E>& input) {
    return sizeof(Array_Data<F>) + Align(input.size() * sizeof(E));
  }

  template <typename Iterator>
  static ValidationError SerializeElements(
      Iterator it,
      size_t num_elements,
      Buffer* buf,
      Array_Data<F>* output,
      const ArrayValidateParams* validate_params) {
    MOJO_DCHECK(!validate_params->element_is_nullable)
        << "Primitive type should be non-nullable";
    MOJO_DCHECK(!validate_params->element_validate_params)
        << "Primitive type should not have array validate params";
    for (size_t i = 0; i < num_elements; ++i, ++it)
      output->at(i) = static_cast<F>(*it);

    return ValidationError::NONE;
  }

  // We can optimize serializing PODs by |memcpy|ing directly.
  // Note that this has precedence over its templated sibling defined above.
  static ValidationError SerializeElements(
      typename Array<E>::Iterator it,
      size_t num_elements,
      Buffer* buf,
      Array_Data<F>* output,
      const ArrayValidateParams* validate_params) {
    MOJO_DCHECK(!validate_params->element_is_nullable)
        << "Primitive type should be non-nullable";
    MOJO_DCHECK(!validate_params->element_validate_params)
        << "Primitive type should not have array validate params";
    if (num_elements)
      memcpy(output->storage(), &(*it), num_elements * sizeof(E));

    return ValidationError::NONE;
  }

  static void DeserializeElements(Array_Data<F>* input, Array<E>* output) {
    std::vector<E> result(input->size());
    if (input->size())
      memcpy(&result[0], input->storage(), input->size() * sizeof(E));
    output->Swap(&result);
  }
};

// Serializes and deserializes arrays of bools.
template <>
struct ArraySerializer<bool, bool, false> {
  static size_t GetSerializedSize(const Array<bool>& input) {
    return sizeof(Array_Data<bool>) + Align((input.size() + 7) / 8);
  }

  template <typename Iterator>
  static ValidationError SerializeElements(
      Iterator it,
      size_t num_elements,
      Buffer* buf,
      Array_Data<bool>* output,
      const ArrayValidateParams* validate_params) {
    MOJO_DCHECK(!validate_params->element_is_nullable)
        << "Primitive type should be non-nullable";
    MOJO_DCHECK(!validate_params->element_validate_params)
        << "Primitive type should not have array validate params";

    // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
    for (size_t i = 0; i < num_elements; ++i, ++it)
      output->at(i) = *it;

    return ValidationError::NONE;
  }

  static void DeserializeElements(Array_Data<bool>* input,
                                  Array<bool>* output) {
    auto result = Array<bool>::New(input->size());
    // TODO(darin): Can this be a memcpy somehow instead of a bit-by-bit copy?
    for (size_t i = 0; i < input->size(); ++i)
      result.at(i) = input->at(i);
    output->Swap(&result);
  }
};

// Serializes and deserializes arrays of handles.
template <typename H>
struct ArraySerializer<ScopedHandleBase<H>, H, false> {
  static size_t GetSerializedSize(const Array<ScopedHandleBase<H>>& input) {
    return sizeof(Array_Data<H>) + Align(input.size() * sizeof(H));
  }

  template <typename Iterator>
  static ValidationError SerializeElements(
      Iterator it,
      size_t num_elements,
      Buffer* buf,
      Array_Data<H>* output,
      const ArrayValidateParams* validate_params) {
    MOJO_DCHECK(!validate_params->element_validate_params)
        << "Handle type should not have array validate params";

    for (size_t i = 0; i < num_elements; ++i, ++it) {
      // Transfer ownership of the handle.
      output->at(i) = it->release();
      if (!validate_params->element_is_nullable && !output->at(i).is_valid()) {
        MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
            ValidationError::UNEXPECTED_INVALID_HANDLE,
            MakeMessageWithArrayIndex(
                "invalid handle in array expecting valid handles", num_elements,
                i));
        return ValidationError::UNEXPECTED_INVALID_HANDLE;
      }
    }

    return ValidationError::NONE;
  }

  static void DeserializeElements(Array_Data<H>* input,
                                  Array<ScopedHandleBase<H>>* output) {
    auto result = Array<ScopedHandleBase<H>>::New(input->size());
    for (size_t i = 0; i < input->size(); ++i)
      result.at(i) = MakeScopedHandle(FetchAndReset(&input->at(i)));
    output->Swap(&result);
  }
};

// Serializes and deserializes arrays of interface requests.
template <typename I>
struct ArraySerializer<InterfaceRequest<I>, MessagePipeHandle, false> {
  static size_t GetSerializedSize(const Array<InterfaceRequest<I>>& input) {
    return sizeof(Array_Data<MessagePipeHandle>) +
           Align(input.size() * sizeof(MessagePipeHandle));
  }

  template <typename Iterator>
  static ValidationError SerializeElements(
      Iterator it,
      size_t num_elements,
      Buffer* buf,
      Array_Data<MessagePipeHandle>* output,
      const ArrayValidateParams* validate_params) {
    MOJO_DCHECK(!validate_params->element_validate_params)
        << "Handle type should not have array validate params";

    for (size_t i = 0; i < num_elements; ++i, ++it) {
      // Transfer ownership of the MessagePipeHandle.
      output->at(i) = it->PassMessagePipe().release();
      if (!validate_params->element_is_nullable && !output->at(i).is_valid()) {
        MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
            ValidationError::UNEXPECTED_INVALID_HANDLE,
            MakeMessageWithArrayIndex(
                "invalid message pipe handle in array expecting valid handles",
                num_elements, i));
        return ValidationError::UNEXPECTED_INVALID_HANDLE;
      }
    }

    return ValidationError::NONE;
  }

  static void DeserializeElements(Array_Data<MessagePipeHandle>* input,
                                  Array<InterfaceRequest<I>>* output) {
    auto result = Array<InterfaceRequest<I>>::New(input->size());
    for (size_t i = 0; i < input->size(); ++i)
      result.at(i) =
          MakeRequest<I>(MakeScopedHandle(FetchAndReset(&input->at(i)))).Pass();
    output->Swap(&result);
  }
};

// Serializes and deserializes arrays of interfaces (interface handles).
template <typename Interface>
struct ArraySerializer<InterfaceHandle<Interface>, Interface_Data, false> {
  static size_t GetSerializedSize(
      const Array<InterfaceHandle<Interface>>& input) {
    return sizeof(Array_Data<Interface_Data>) +
           Align(input.size() * sizeof(Interface_Data));
  }

  template <typename Iterator>
  static ValidationError SerializeElements(
      Iterator it,
      size_t num_elements,
      Buffer* buf,
      Array_Data<Interface_Data>* output,
      const ArrayValidateParams* validate_params) {
    MOJO_DCHECK(!validate_params->element_validate_params)
        << "Interface type should not have array validate params";

    for (size_t i = 0; i < num_elements; ++i, ++it) {
      // Transfer ownership of the handle.
      internal::InterfaceHandleToData(it->Pass(), &output->at(i));
      if (!validate_params->element_is_nullable &&
          !output->at(i).handle.is_valid()) {
        MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
            ValidationError::UNEXPECTED_INVALID_HANDLE,
            MakeMessageWithArrayIndex(
                "invalid handle in array expecting valid handles", num_elements,
                i));
        return ValidationError::UNEXPECTED_INVALID_HANDLE;
      }
    }

    return ValidationError::NONE;
  }

  static void DeserializeElements(Array_Data<Interface_Data>* input,
                                  Array<InterfaceHandle<Interface>>* output) {
    auto result = Array<InterfaceHandle<Interface>>::New(input->size());
    for (size_t i = 0; i < input->size(); ++i)
      internal::InterfaceDataToHandle(&input->at(i), &result.at(i));
    output->Swap(&result);
  }
};

// This template must only apply to pointer mojo entity (structs, arrays,
// strings).  This is done by ensuring that WrapperTraits<S>::DataType is a
// pointer.
template <typename S>
struct ArraySerializer<
    S,
    typename std::enable_if<
        std::is_pointer<typename WrapperTraits<S>::DataType>::value,
        typename WrapperTraits<S>::DataType>::type,
    false> {
  typedef
      typename std::remove_pointer<typename WrapperTraits<S>::DataType>::type
          S_Data;
  static size_t GetSerializedSize(const Array<S>& input) {
    size_t size = sizeof(Array_Data<S_Data*>) +
                  input.size() * sizeof(StructPointer<S_Data>);
    for (size_t i = 0; i < input.size(); ++i) {
      if (!input[i].is_null())
        size += GetSerializedSize_(*(UnwrapConstStructPtr<S>::value(input[i])));
    }
    return size;
  }

  template <typename Iterator>
  static ValidationError SerializeElements(
      Iterator it,
      size_t num_elements,
      Buffer* buf,
      Array_Data<S_Data*>* output,
      const ArrayValidateParams* validate_params) {
    for (size_t i = 0; i < num_elements; ++i, ++it) {
      S_Data* element;
      auto retval = SerializeCaller::Run(
          &(*it), buf, &element, validate_params->element_validate_params);
      if (retval != ValidationError::NONE)
        return retval;

      output->at(i) = element;
      if (!validate_params->element_is_nullable && !element) {
        MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
            ValidationError::UNEXPECTED_NULL_POINTER,
            MakeMessageWithArrayIndex("null in array expecting valid pointers",
                                      num_elements, i));
        return ValidationError::UNEXPECTED_NULL_POINTER;
      }
    }

    return ValidationError::NONE;
  }

  static void DeserializeElements(Array_Data<S_Data*>* input,
                                  Array<S>* output) {
    auto result = Array<S>::New(input->size());
    for (size_t i = 0; i < input->size(); ++i) {
      DeserializeCaller::Run(input->at(i), &result[i]);
    }
    output->Swap(&result);
  }

 private:
  // SerializeCaller template is used by |ArraySerializer| to dispatch a
  // serialize call on a non-POD type.  This template is defined outside
  // |ArraySerializer| since you cannot specialize a struct within a class
  // definition.
  struct SerializeCaller {
    // This template needs to be suppressed if |T| is |String|, otherwise it
    // takes precedence over the |String|-overloaded Run() below.
    template <
        typename T,
        typename =
            typename std::enable_if<!std::is_same<T, String>::value, T>::type>
    static ValidationError Run(T* input,
                               Buffer* buf,
                               typename WrapperTraits<T>::DataType* output,
                               const ArrayValidateParams* validate_params) {
      MOJO_DCHECK(!validate_params)
          << "Struct type should not have array validate params";
      return Serialize_(UnwrapStructPtr<T>::value(*input), buf, output);
    }

    static ValidationError Run(const String* input,
                               Buffer* buf,
                               String_Data** output,
                               const ArrayValidateParams* validate_params) {
      MOJO_DCHECK(validate_params &&
                  !validate_params->element_validate_params &&
                  !validate_params->element_is_nullable &&
                  validate_params->expected_num_elements == 0)
          << "String type has unexpected array validate params";
      SerializeString_(*input, buf, output);
      return ValidationError::NONE;
    }

    template <typename T>
    static ValidationError Run(Array<T>* input,
                               Buffer* buf,
                               typename Array<T>::Data_** output,
                               const ArrayValidateParams* validate_params) {
      return SerializeArray_(input, buf, output, validate_params);
    }

    template <typename Key, typename Value>
    static ValidationError Run(Map<Key, Value>* input,
                               Buffer* buf,
                               typename Map<Key, Value>::Data_** output,
                               const ArrayValidateParams* validate_params) {
      return SerializeMap_(input, buf, output, validate_params);
    }
  };

  struct DeserializeCaller {
    template <typename T>
    static void Run(typename WrapperTraits<T>::DataType input, T* output) {
      Deserialize_(input, output);
    }

    // Since Deserialize_ takes in a |Struct*| (not |StructPtr|), we need to
    // initialize the |StructPtr| here before deserializing into its underlying
    // data.
    // TODO(vardhan):  Either all containers, or just Deserialize_(), should
    // support taking in an allocator.
    template <typename T>
    static void Run(typename WrapperTraits<StructPtr<T>>::DataType input,
                    StructPtr<T>* output) {
      if (input) {
        *output = T::New();
        Deserialize_(input, output->get());
      }
    }

    template <typename T>
    static void Run(typename WrapperTraits<InlinedStructPtr<T>>::DataType input,
                    InlinedStructPtr<T>* output) {
      if (input) {
        *output = T::New();
        Deserialize_(input, output->get());
      }
    }
  };
};

// Handles serialization and deserialization of arrays of unions.
template <typename U, typename U_Data>
struct ArraySerializer<U, U_Data, true> {
  static size_t GetSerializedSize(const Array<U>& input) {
    size_t size = sizeof(Array_Data<U_Data>);
    for (size_t i = 0; i < input.size(); ++i) {
      // GetSerializedSize_ will account for both the data in the union and the
      // space in the array used to hold the union.
      size += GetSerializedSize_(input[i]);
    }
    return size;
  }

  template <typename Iterator>
  static ValidationError SerializeElements(
      Iterator it,
      size_t num_elements,
      Buffer* buf,
      Array_Data<U_Data>* output,
      const ArrayValidateParams* validate_params) {
    for (size_t i = 0; i < num_elements; ++i, ++it) {
      U_Data* result = output->storage() + i;
      auto retval = SerializeUnion_(it->get(), buf, &result);
      if (retval != ValidationError::NONE)
        return retval;
      if (!validate_params->element_is_nullable && output->at(i).is_null()) {
        MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(

            ValidationError::UNEXPECTED_NULL_POINTER,
            MakeMessageWithArrayIndex("null in array expecting valid unions",
                                      num_elements, i));
        return ValidationError::UNEXPECTED_NULL_POINTER;
      }
    }

    return ValidationError::NONE;
  }

  static void DeserializeElements(Array_Data<U_Data>* input, Array<U>* output) {
    auto result = Array<U>::New(input->size());
    for (size_t i = 0; i < input->size(); ++i) {
      auto& elem = input->at(i);
      if (!elem.is_null()) {
        using UnwrapedUnionType = typename RemoveStructPtr<U>::type;
        result[i] = UnwrapedUnionType::New();
        Deserialize_(&elem, result[i].get());
      }
    }
    output->Swap(&result);
  }
};

}  // namespace internal

template <typename E>
inline size_t GetSerializedSize_(const Array<E>& input) {
  if (!input)
    return 0;
  using F = typename internal::WrapperTraits<E>::DataType;
  return internal::ArraySerializer<E, F>::GetSerializedSize(input);
}

// SerializeArray_ 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
// SerializeArray_), in which case |buf| is also partially consumed.
template <typename E, typename F>
inline internal::ValidationError SerializeArray_(
    Array<E>* input,
    internal::Buffer* buf,
    internal::Array_Data<F>** output,
    const internal::ArrayValidateParams* validate_params) {
  MOJO_DCHECK(input);
  if (!*input) {
    // It is up to the caller to make sure the given |Array| is not null if it
    // is not nullable.
    *output = nullptr;
    return internal::ValidationError::NONE;
  }

  if (validate_params->expected_num_elements != 0 &&
      input->size() != validate_params->expected_num_elements) {
    MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
        internal::ValidationError::UNEXPECTED_ARRAY_HEADER,
        internal::MakeMessageWithExpectedArraySize(
            "fixed-size array has wrong number of elements", input->size(),
            validate_params->expected_num_elements));
    return internal::ValidationError::UNEXPECTED_ARRAY_HEADER;
  }

  internal::Array_Data<F>* result =
      internal::Array_Data<F>::New(input->size(), buf);
  auto retval = internal::ArraySerializer<E, F>::SerializeElements(
      input->begin(), input->size(), buf, result, validate_params);
  if (retval != internal::ValidationError::NONE)
    return retval;

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

template <typename E, typename F>
inline void Deserialize_(internal::Array_Data<F>* input, Array<E>* output) {
  if (input) {
    internal::ArraySerializer<E, F>::DeserializeElements(input, output);
  } else {
    output->reset();
  }
}

}  // namespace mojo

#endif  // MOJO_PUBLIC_CPP_BINDINGS_LIB_ARRAY_SERIALIZATION_H_
