// Copyright 2018 The Fuchsia 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 LIB_FIDL_CPP_CLONE_H_
#define LIB_FIDL_CPP_CLONE_H_

#include <zircon/assert.h>

#include <array>
#include <memory>

#include "lib/fidl/cpp/string.h"
#include "lib/fidl/cpp/traits.h"
#include "lib/fidl/cpp/vector.h"
#include "types.h"

namespace fidl {

#ifdef __Fuchsia__
namespace internal {

template <typename T>
inline typename std::enable_if<zx::object_traits<T>::supports_duplication, zx_status_t>::type
CloneKernelObject(const zx::object<T>& object, zx::object<T>* result) {
  return object.duplicate(ZX_RIGHT_SAME_RIGHTS, result);
}

template <typename T>
inline typename std::enable_if<!zx::object_traits<T>::supports_duplication, zx_status_t>::type
CloneKernelObject(const zx::object<T>& object, zx::object<T>* result) {
  return ZX_ERR_ACCESS_DENIED;
}

}  // namespace internal
#endif  // __Fuchsia__

// Deep copies the contents of |value| into |result|.
// This operation also attempts to duplicate any handles the value contains.
//
// Returns an error if the value could not be cloned, perhaps because a
// handle was not duplicable.
//
// There are many overloads of this function with the following signature:
//   zx_status_t Clone(const T& value, T* result);
template <typename T>
inline typename std::enable_if<IsPrimitive<T>::value, zx_status_t>::type Clone(const T& value,
                                                                               T* result) {
  *result = value;
  return ZX_OK;
}

// Forward-declare some templates:
template <typename T, size_t N>
inline typename std::enable_if<IsPrimitive<T>::value || IsStdString<T>::value, zx_status_t>::type
Clone(const std::array<T, N>& value, std::array<T, N>* result);
template <typename T, size_t N>
inline typename std::enable_if<!IsPrimitive<T>::value && !IsStdString<T>::value, zx_status_t>::type
Clone(const std::array<T, N>& value, std::array<T, N>* result);

template <typename T>
inline
#ifdef __Fuchsia__
    typename std::enable_if<!IsPrimitive<T>::value && !std::is_base_of<zx::object_base, T>::value &&
                                !IsStdVector<T>::value && !IsStdArray<T>::value,
                            zx_status_t>::type
#else   // __Fuchsia__
    typename std::enable_if<!IsPrimitive<T>::value && !IsStdVector<T>::value &&
                                !IsStdArray<T>::value,
                            zx_status_t>::type
#endif  // __Fuchsia__
    Clone(const T& value, T* result) {
  return value.Clone(result);
}

#ifdef __Fuchsia__
template <typename T>
zx_status_t Clone(const zx::object<T>& value, zx::object<T>* result) {
  if (!value) {
    result->reset();
    return ZX_OK;
  }
  return internal::CloneKernelObject(value, result);
}
#endif  // __Fuchsia__

zx_status_t Clone(const StringPtr& value, StringPtr* result);
zx_status_t Clone(const ::std::string& value, std::string* result);

template <typename T>
inline zx_status_t Clone(const std::unique_ptr<T>& value, std::unique_ptr<T>* result) {
  if (!value) {
    result->reset();
    return ZX_OK;
  }
  *result = std::make_unique<T>();
  return Clone(*value, result->get());
}

template <typename T>
inline typename std::enable_if<IsPrimitive<T>::value || IsStdString<T>::value, zx_status_t>::type
Clone(const VectorPtr<T>& value, VectorPtr<T>* result) {
  if (!value.has_value()) {
    result->reset();
    return ZX_OK;
  }
  *result = *value;
  return ZX_OK;
}

template <typename T>
inline typename std::enable_if<IsPrimitive<T>::value || IsStdString<T>::value, zx_status_t>::type
Clone(const ::std::vector<T>& value, ::std::vector<T>* result) {
  *result = value;
  return ZX_OK;
}

template <typename T>
inline typename std::enable_if<!IsPrimitive<T>::value && !IsStdString<T>::value, zx_status_t>::type
Clone(const ::std::vector<T>& value, ::std::vector<T>* result) {
  result->resize(value.size());
  for (size_t i = 0; i < value.size(); ++i) {
    zx_status_t status = Clone(value.at(i), &result->at(i));
    if (status != ZX_OK)
      return status;
  }
  return ZX_OK;
}

template <typename T>
inline typename std::enable_if<!IsPrimitive<T>::value && !IsStdString<T>::value, zx_status_t>::type
Clone(const VectorPtr<T>& value, VectorPtr<T>* result) {
  if (!value.has_value()) {
    result->reset();
    return ZX_OK;
  }
  result->emplace();
  (*result)->resize(value->size());
  for (size_t i = 0; i < value->size(); ++i) {
    zx_status_t status = Clone(value->at(i), &(*result)->at(i));
    if (status != ZX_OK)
      return status;
  }
  return ZX_OK;
}

template <typename T, size_t N>
inline typename std::enable_if<IsPrimitive<T>::value || IsStdString<T>::value, zx_status_t>::type
Clone(const ::std::array<T, N>& value, ::std::array<T, N>* result) {
  *result = value;
  return ZX_OK;
}

template <typename T, size_t N>
inline typename std::enable_if<!IsPrimitive<T>::value && !IsStdString<T>::value, zx_status_t>::type
Clone(const std::array<T, N>& value, std::array<T, N>* result) {
  for (size_t i = 0; i < N; ++i) {
    zx_status_t status = Clone(value[i], &result->at(i));
    if (status != ZX_OK)
      return status;
  }
  return ZX_OK;
}

inline zx_status_t Clone(const UnknownBytes& value, UnknownBytes* result) {
  result->bytes = value.bytes;
  return ZX_OK;
}

inline zx_status_t Clone(const ::std::map<uint64_t, ::std::vector<uint8_t>>& value,
                         ::std::map<uint64_t, ::std::vector<uint8_t>>* result) {
  *result = value;
  return ZX_OK;
}

#ifdef __Fuchsia__
inline zx_status_t Clone(const UnknownData& value, UnknownData* result) {
  result->bytes = value.bytes;
  return Clone(value.handles, &(result->handles));
}

inline zx_status_t Clone(const ::std::map<uint64_t, UnknownData>& value,
                         ::std::map<uint64_t, UnknownData>* result) {
  result->clear();
  for (const auto& pair : value) {
    auto field = result->emplace(std::piecewise_construct, std::forward_as_tuple(pair.first),
                                     std::forward_as_tuple());
    zx_status_t status = Clone(pair.second, &field.first->second);
    if (status != ZX_OK)
      return status;
  }
  return ZX_OK;
}
#endif

// Returns a deep copy of |value|.
// This operation also attempts to duplicate any handles the value contains.
//
// Crashes the program if the value could not be cloned, perhaps because a
// handle was not duplicable.
template <typename T>
inline T Clone(const T& value) {
  T clone;
  zx_status_t status = Clone(value, &clone);
  ZX_ASSERT(status == ZX_OK);
  return clone;
}

}  // namespace fidl

#endif  // LIB_FIDL_CPP_CLONE_H_
