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

#include "lib/sysmem-version/sysmem-version.h"

#include <fuchsia/sysmem/c/fidl.h>
#include <fuchsia/sysmem/llcpp/fidl.h>
#include <fuchsia/sysmem2/llcpp/fidl.h>
#include <inttypes.h>
#include <lib/fidl-async-2/fidl_struct.h>
#include <zircon/assert.h>

#include <map>
#include <set>

#include "log.h"

namespace sysmem {
namespace {

// Can be replaced with std::remove_cvref<> when C++20.
template <typename T>
struct RemoveCVRef
    : ::sysmem::internal::TypeIdentity<std::remove_cv_t<std::remove_reference_t<T>>> {};
template <typename T>
using RemoveCVRef_t = typename RemoveCVRef<T>::type;

template <typename T, typename Enable = void>
struct IsFidlScalar : std::false_type {};
template <typename T>
struct IsFidlScalar<
    T, typename std::enable_if<fidl::IsFidlType<T>::value &&
                               (std::is_arithmetic<T>::value || std::is_enum<T>::value)>::type>
    : std::true_type {};

template <typename V2Type, typename V1Type, typename Enable = void>
struct IsCompatibleFidlScalarTypes : std::false_type {};
template <typename V2Type, typename V1Type>
struct IsCompatibleFidlScalarTypes<
    V2Type, V1Type,
    typename std::enable_if<
        // must be able to write to v2
        !std::is_const<typename std::remove_reference<V2Type>::type>::value &&
        IsFidlScalar<typename RemoveCVRef<V2Type>::type>::value &&
        IsFidlScalar<typename RemoveCVRef<V1Type>::type>::value &&
        std::is_same<typename ::sysmem::internal::UnderlyingTypeOrType<
                         typename RemoveCVRef<V2Type>::type>::type,
                     typename ::sysmem::internal::UnderlyingTypeOrType<
                         typename RemoveCVRef<V1Type>::type>::type>::value>::type>
    : std::true_type {};
template <typename V2, typename V1>
inline constexpr bool IsCompatibleFidlScalarTypes_v = IsCompatibleFidlScalarTypes<V2, V1>::value;

// The C++ style guide discourages macros, but does not prohibit them.  To operate on a bunch of
// separate fields with different names, it's a choice among tons of error-prone repetitive
// verbosity, macros, or more abstraction than I think anyone would want.  Macros are the least-bad
// option (among those options considred so far).  Feel free to propose another option.

// This macro is needed to cut down on the noise from the exact same error check occurring every
// place we might early return a failure.
#define OK_OR_RET_ERROR(foo)  \
  do {                        \
    if (!(foo).is_ok()) {     \
      LOG(ERROR, "!is_ok()"); \
      return fit::error();    \
    }                         \
  } while (false)

// This macro is needed to ensure that we don't cross-wire fields as we're converting from V1 to V2
// and to cut down on the noise from the exact same code structure for most fields.  Also, this way
// we can include a static check that the type of the v2 field exactly matches the type of the v1
// field, which doesn't generate any actual code, yet needs to be repeated for each field being
// converted.
//
// This handles scalar fields, including enum fields.  It doesn't handle vector fields, tensor
// fields, struct fields, or table fields.
//
// All bool fields are set regardless of false or true.  Other scalar fields are only set if not
// equal to zero.
#define PROCESS_SCALAR_FIELD_V1(field_name)                                      \
  do {                                                                           \
    using V2FieldType = std::remove_reference<decltype(v2b.field_name())>::type; \
    /* double parens are significant here */                                     \
    using V1FieldType = std::remove_reference<decltype((v1.field_name))>::type;  \
    static_assert(IsCompatibleFidlScalarTypes_v<V2FieldType, V1FieldType>);      \
    if (std::is_same<bool, RemoveCVRef<V1FieldType>::type>::value ||             \
        static_cast<bool>(v1.field_name)) {                                      \
      v2b.set_##field_name(allocator, static_cast<V2FieldType>(v1.field_name));  \
    }                                                                            \
  } while (false)

#define PROCESS_SCALAR_FIELD_V2(field_name)                                      \
  do {                                                                           \
    using V1FieldType = decltype(v1.field_name);                                 \
    using V2FieldType = std::remove_reference<decltype(v2.field_name())>::type;  \
    static_assert(IsCompatibleFidlScalarTypes<V1FieldType, V2FieldType>::value); \
    if (v2.has_##field_name()) {                                                 \
      v1.field_name = static_cast<V1FieldType>(v2.field_name());                 \
    } else {                                                                     \
      v1.field_name = static_cast<V1FieldType>(0);                               \
    }                                                                            \
  } while (false)

#define ASSIGN_SCALAR(dst, src)                                     \
  do {                                                              \
    using DstType = decltype((dst));                                \
    using SrcType = decltype((src));                                \
    static_assert(IsCompatibleFidlScalarTypes_v<DstType, SrcType>); \
    using DstNoRef = typename std::remove_reference<DstType>::type; \
    (dst) = static_cast<DstNoRef>(src);                             \
  } while (false)

template <size_t N>
fit::result<fidl::VectorView<fuchsia_sysmem2::wire::HeapType>> V2CopyFromV1HeapPermittedArray(
    fidl::AnyAllocator& allocator, const fidl::Array<fuchsia_sysmem::wire::HeapType, N>& v1a,
    const uint32_t v1_count) {
  ZX_DEBUG_ASSERT(v1_count);
  if (v1_count > v1a.size()) {
    LOG(ERROR, "v1_count > v1a.size() - v1_count: %u v1a.size(): %zu", v1_count, v1a.size());
    return fit::error();
  }
  fidl::VectorView<fuchsia_sysmem2::wire::HeapType> v2a(allocator, v1_count);
  for (uint32_t i = 0; i < v1_count; i++) {
    ASSIGN_SCALAR(v2a[i], v1a[i]);
  }
  return fit::ok(std::move(v2a));
}

template <size_t N>
fit::result<fidl::VectorView<fuchsia_sysmem2::wire::ColorSpace>> V2CopyFromV1ColorSpaceArray(
    fidl::AnyAllocator& allocator, const fidl::Array<fuchsia_sysmem::wire::ColorSpace, N>& v1a,
    uint32_t v1_count) {
  ZX_DEBUG_ASSERT(v1_count);
  if (v1_count > v1a.size()) {
    LOG(ERROR, "v1_count > v1a.size() - v1_count: %u v1a.size(): %zu", v1_count, v1a.size());
    return fit::error();
  }
  fidl::VectorView<fuchsia_sysmem2::wire::ColorSpace> v2a(allocator, v1_count);
  for (uint32_t i = 0; i < v1_count; i++) {
    v2a[i] = V2CopyFromV1ColorSpace(allocator, v1a[i]);
  }
  return fit::ok(std::move(v2a));
}

template <size_t N>
fit::result<fidl::VectorView<fuchsia_sysmem2::wire::ImageFormatConstraints>>
V2CopyFromV1ImageFormatConstraintsArray(
    fidl::AnyAllocator& allocator,
    const fidl::Array<fuchsia_sysmem::wire::ImageFormatConstraints, N>& v1a,
    const uint32_t v1_count) {
  ZX_DEBUG_ASSERT(v1_count);
  if (v1_count > v1a.size()) {
    LOG(ERROR, "v1_count > v1a.size() - v1_count: %u v1a.size(): %zu", v1_count, v1a.size());
    return fit::error();
  }
  fidl::VectorView<fuchsia_sysmem2::wire::ImageFormatConstraints> v2a(allocator, v1_count);
  for (uint32_t i = 0; i < v1_count; i++) {
    auto result = V2CopyFromV1ImageFormatConstraints(allocator, v1a[i]);
    OK_OR_RET_ERROR(result);
    v2a[i] = result.take_value();
  }
  return fit::ok(std::move(v2a));
}

fit::result<> V2CopyFromV1BufferCollectionConstraintsMain(
    fidl::AnyAllocator& allocator, fuchsia_sysmem2::wire::BufferCollectionConstraints* v2b_param,
    const fuchsia_sysmem::wire::BufferCollectionConstraints& v1) {
  ZX_DEBUG_ASSERT(v2b_param);
  fuchsia_sysmem2::wire::BufferCollectionConstraints& v2b = *v2b_param;

  // This sets usage regardless of whether the client set any usage bits within usage.  That's
  // checked later (regardless of v1 or v2 client).  If a v1 client said !has_constraints, we
  // won't call the current method and usage field will remain un-set so that
  // Constraints2.IsEmpty() overall.
  {
    auto result = V2CopyFromV1BufferUsage(allocator, v1.usage);
    OK_OR_RET_ERROR(result);
    v2b.set_usage(allocator, result.take_value());
  }

  PROCESS_SCALAR_FIELD_V1(min_buffer_count_for_camping);
  PROCESS_SCALAR_FIELD_V1(min_buffer_count_for_dedicated_slack);
  PROCESS_SCALAR_FIELD_V1(min_buffer_count_for_shared_slack);
  PROCESS_SCALAR_FIELD_V1(min_buffer_count);
  PROCESS_SCALAR_FIELD_V1(max_buffer_count);
  if (v1.has_buffer_memory_constraints) {
    auto result = V2CopyFromV1BufferMemoryConstraints(allocator, v1.buffer_memory_constraints);
    OK_OR_RET_ERROR(result);
    v2b.set_buffer_memory_constraints(allocator, result.take_value());
  }
  if (v1.image_format_constraints_count) {
    auto result = V2CopyFromV1ImageFormatConstraintsArray(allocator, v1.image_format_constraints,
                                                          v1.image_format_constraints_count);
    OK_OR_RET_ERROR(result);
    v2b.set_image_format_constraints(allocator, result.take_value());
  }
  return fit::ok();
}

fit::result<> V2CopyFromV1BufferCollectionConstraintsAuxBuffers(
    fidl::AnyAllocator& allocator, fuchsia_sysmem2::wire::BufferCollectionConstraints* v2b_param,
    const fuchsia_sysmem::wire::BufferCollectionConstraintsAuxBuffers& v1) {
  ZX_DEBUG_ASSERT(v2b_param);
  fuchsia_sysmem2::wire::BufferCollectionConstraints& v2b = *v2b_param;
  PROCESS_SCALAR_FIELD_V1(need_clear_aux_buffers_for_secure);
  PROCESS_SCALAR_FIELD_V1(allow_clear_aux_buffers_for_secure);
  return fit::ok();
}

}  // namespace

fuchsia_sysmem2::wire::PixelFormat V2CopyFromV1PixelFormat(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem::wire::PixelFormat& v1) {
  fuchsia_sysmem2::wire::PixelFormat v2b(allocator);
  PROCESS_SCALAR_FIELD_V1(type);
  if (v1.has_format_modifier) {
    v2b.set_format_modifier_value(allocator, v1.format_modifier.value);
  }
  return v2b;
}

fuchsia_sysmem2::wire::PixelFormat V2CopyFromV1PixelFormat(fidl::AnyAllocator& allocator,
                                                           const fuchsia_sysmem_PixelFormat& v1) {
  using CStruct = FidlStruct<fuchsia_sysmem_PixelFormat, fuchsia_sysmem::wire::PixelFormat>;
  return V2CopyFromV1PixelFormat(allocator, *CStruct::BorrowAsLlcpp(&v1));
}

fuchsia_sysmem2::wire::ColorSpace V2CopyFromV1ColorSpace(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem::wire::ColorSpace& v1) {
  fuchsia_sysmem2::wire::ColorSpace v2b(allocator);
  PROCESS_SCALAR_FIELD_V1(type);
  return v2b;
}

fuchsia_sysmem2::wire::ColorSpace V2CopyFromV1ColorSpace(fidl::AnyAllocator& allocator,
                                                         const fuchsia_sysmem_ColorSpace& v1) {
  using CStruct = FidlStruct<fuchsia_sysmem_ColorSpace, fuchsia_sysmem::wire::ColorSpace>;
  return V2CopyFromV1ColorSpace(allocator, *CStruct::BorrowAsLlcpp(&v1));
}

fit::result<fuchsia_sysmem2::wire::ImageFormatConstraints> V2CopyFromV1ImageFormatConstraints(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem::wire::ImageFormatConstraints& v1) {
  fuchsia_sysmem2::wire::ImageFormatConstraints v2b(allocator);
  v2b.set_pixel_format(allocator, V2CopyFromV1PixelFormat(allocator, v1.pixel_format));
  if (v1.color_spaces_count) {
    auto result = V2CopyFromV1ColorSpaceArray(allocator, v1.color_space, v1.color_spaces_count);
    OK_OR_RET_ERROR(result);
    v2b.set_color_spaces(allocator, result.take_value());
  }
  PROCESS_SCALAR_FIELD_V1(min_coded_width);
  PROCESS_SCALAR_FIELD_V1(max_coded_width);
  PROCESS_SCALAR_FIELD_V1(min_coded_height);
  PROCESS_SCALAR_FIELD_V1(max_coded_height);
  PROCESS_SCALAR_FIELD_V1(min_bytes_per_row);
  PROCESS_SCALAR_FIELD_V1(max_bytes_per_row);
  PROCESS_SCALAR_FIELD_V1(max_coded_width_times_coded_height);
  if (v1.layers) {
    if (v1.layers > 1) {
      LOG(ERROR, "v1.layers > 1");
      return fit::error();
    }
    // v2 ImageFormatConstraints doesn't have layers field (at least not yet), on purpose.  If it
    // ever gains a layers field, most likely we won't translate the v1 layers field to any v2
    // layers field.
  }
  PROCESS_SCALAR_FIELD_V1(coded_width_divisor);
  PROCESS_SCALAR_FIELD_V1(coded_height_divisor);
  PROCESS_SCALAR_FIELD_V1(bytes_per_row_divisor);
  PROCESS_SCALAR_FIELD_V1(start_offset_divisor);
  PROCESS_SCALAR_FIELD_V1(display_width_divisor);
  PROCESS_SCALAR_FIELD_V1(display_height_divisor);
  PROCESS_SCALAR_FIELD_V1(required_min_coded_width);
  PROCESS_SCALAR_FIELD_V1(required_max_coded_width);
  PROCESS_SCALAR_FIELD_V1(required_min_coded_height);
  PROCESS_SCALAR_FIELD_V1(required_max_coded_height);
  PROCESS_SCALAR_FIELD_V1(required_min_bytes_per_row);
  PROCESS_SCALAR_FIELD_V1(required_max_bytes_per_row);
  return fit::ok(std::move(v2b));
}

fit::result<fuchsia_sysmem2::wire::ImageFormatConstraints> V2CopyFromV1ImageFormatConstraints(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem_ImageFormatConstraints& v1) {
  using CStruct = FidlStruct<fuchsia_sysmem_ImageFormatConstraints,
                             fuchsia_sysmem::wire::ImageFormatConstraints>;
  return V2CopyFromV1ImageFormatConstraints(allocator, *CStruct::BorrowAsLlcpp(&v1));
}

fit::result<fuchsia_sysmem2::wire::BufferUsage> V2CopyFromV1BufferUsage(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem::wire::BufferUsage& v1) {
  fuchsia_sysmem2::wire::BufferUsage v2b(allocator);
  using foo = std::remove_reference<decltype((v1.none))>::type;
  static_assert(std::is_const<foo>::value);
  PROCESS_SCALAR_FIELD_V1(none);
  PROCESS_SCALAR_FIELD_V1(cpu);
  PROCESS_SCALAR_FIELD_V1(vulkan);
  PROCESS_SCALAR_FIELD_V1(display);
  PROCESS_SCALAR_FIELD_V1(video);
  return fit::ok(std::move(v2b));
}

fit::result<fuchsia_sysmem2::wire::BufferUsage> V2CopyFromV1BufferUsage(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem_BufferUsage& v1) {
  using CStruct = FidlStruct<fuchsia_sysmem_BufferUsage, fuchsia_sysmem::wire::BufferUsage>;
  return V2CopyFromV1BufferUsage(allocator, *CStruct::BorrowAsLlcpp(&v1));
}

fit::result<fuchsia_sysmem2::wire::BufferMemoryConstraints> V2CopyFromV1BufferMemoryConstraints(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem::wire::BufferMemoryConstraints& v1) {
  fuchsia_sysmem2::wire::BufferMemoryConstraints v2b(allocator);
  PROCESS_SCALAR_FIELD_V1(min_size_bytes);
  PROCESS_SCALAR_FIELD_V1(max_size_bytes);
  PROCESS_SCALAR_FIELD_V1(physically_contiguous_required);
  PROCESS_SCALAR_FIELD_V1(secure_required);
  PROCESS_SCALAR_FIELD_V1(ram_domain_supported);
  PROCESS_SCALAR_FIELD_V1(cpu_domain_supported);
  PROCESS_SCALAR_FIELD_V1(inaccessible_domain_supported);
  if (v1.heap_permitted_count) {
    auto result =
        V2CopyFromV1HeapPermittedArray(allocator, v1.heap_permitted, v1.heap_permitted_count);
    OK_OR_RET_ERROR(result);
    v2b.set_heap_permitted(allocator, result.take_value());
  }
  return fit::ok(std::move(v2b));
}

fit::result<fuchsia_sysmem2::wire::BufferMemoryConstraints> V2CopyFromV1BufferMemoryConstraints(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem_BufferMemoryConstraints& v1) {
  using CStruct = FidlStruct<fuchsia_sysmem_BufferMemoryConstraints,
                             fuchsia_sysmem::wire::BufferMemoryConstraints>;
  return V2CopyFromV1BufferMemoryConstraints(allocator, *CStruct::BorrowAsLlcpp(&v1));
}

// If !v1 && !aux_buffers_v1, the result will be fit::is_ok(), but result.value().IsEmpty().
fit::result<fuchsia_sysmem2::wire::BufferCollectionConstraints>
V2CopyFromV1BufferCollectionConstraints(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem::wire::BufferCollectionConstraints* v1,
    const fuchsia_sysmem::wire::BufferCollectionConstraintsAuxBuffers* aux_buffers_v1) {
  // Should be enforced by the caller.
  ZX_DEBUG_ASSERT(v1 || !aux_buffers_v1);
  fuchsia_sysmem2::wire::BufferCollectionConstraints v2b(allocator);

  if (v1) {
    auto result = V2CopyFromV1BufferCollectionConstraintsMain(allocator, &v2b, *v1);
    OK_OR_RET_ERROR(result);
  }

  if (aux_buffers_v1) {
    auto result =
        V2CopyFromV1BufferCollectionConstraintsAuxBuffers(allocator, &v2b, *aux_buffers_v1);
    OK_OR_RET_ERROR(result);
  }

  return fit::ok(std::move(v2b));
}

fit::result<fuchsia_sysmem2::wire::BufferCollectionConstraints>
V2CopyFromV1BufferCollectionConstraints(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem_BufferCollectionConstraints* v1,
    const fuchsia_sysmem_BufferCollectionConstraintsAuxBuffers* aux_buffers_v1) {
  using CStructMain = FidlStruct<fuchsia_sysmem_BufferCollectionConstraints,
                                 fuchsia_sysmem::wire::BufferCollectionConstraints>;
  using CStructAux = FidlStruct<fuchsia_sysmem_BufferCollectionConstraintsAuxBuffers,
                                fuchsia_sysmem::wire::BufferCollectionConstraintsAuxBuffers>;
  return V2CopyFromV1BufferCollectionConstraints(allocator, CStructMain::BorrowAsLlcpp(v1),
                                                 CStructAux::BorrowAsLlcpp(aux_buffers_v1));
}

fit::result<fuchsia_sysmem2::wire::ImageFormat> V2CopyFromV1ImageFormat(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem::wire::ImageFormat_2& v1) {
  fuchsia_sysmem2::wire::ImageFormat v2b(allocator);
  v2b.set_pixel_format(allocator, V2CopyFromV1PixelFormat(allocator, v1.pixel_format));
  PROCESS_SCALAR_FIELD_V1(coded_width);
  PROCESS_SCALAR_FIELD_V1(coded_height);
  PROCESS_SCALAR_FIELD_V1(bytes_per_row);
  PROCESS_SCALAR_FIELD_V1(display_width);
  PROCESS_SCALAR_FIELD_V1(display_height);
  if (v1.layers > 1) {
    LOG(ERROR, "v1.layers > 1");
    return fit::error();
  }
  v2b.set_color_space(allocator, V2CopyFromV1ColorSpace(allocator, v1.color_space));
  if (v1.has_pixel_aspect_ratio) {
    v2b.set_pixel_aspect_ratio_width(allocator, v1.pixel_aspect_ratio_width);
    v2b.set_pixel_aspect_ratio_height(allocator, v1.pixel_aspect_ratio_height);
  } else {
    ZX_DEBUG_ASSERT(!v2b.has_pixel_aspect_ratio_width());
    ZX_DEBUG_ASSERT(!v2b.has_pixel_aspect_ratio_height());
  }
  return fit::ok(std::move(v2b));
}

fit::result<fuchsia_sysmem2::wire::ImageFormat> V2CopyFromV1ImageFormat(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem_ImageFormat_2& v1) {
  using CStruct = FidlStruct<fuchsia_sysmem_ImageFormat_2, fuchsia_sysmem::wire::ImageFormat_2>;
  return V2CopyFromV1ImageFormat(allocator, *CStruct::BorrowAsLlcpp(&v1));
}

[[nodiscard]] fuchsia_sysmem2::wire::BufferMemorySettings V2CopyFromV1BufferMemorySettings(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem::wire::BufferMemorySettings& v1) {
  fuchsia_sysmem2::wire::BufferMemorySettings v2b(allocator);
  PROCESS_SCALAR_FIELD_V1(size_bytes);
  PROCESS_SCALAR_FIELD_V1(is_physically_contiguous);
  PROCESS_SCALAR_FIELD_V1(is_secure);
  PROCESS_SCALAR_FIELD_V1(coherency_domain);
  PROCESS_SCALAR_FIELD_V1(heap);
  return v2b;
}

fit::result<fuchsia_sysmem2::wire::SingleBufferSettings> V2CopyFromV1SingleBufferSettings(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem::wire::SingleBufferSettings& v1) {
  fuchsia_sysmem2::wire::SingleBufferSettings v2b(allocator);
  v2b.set_buffer_settings(allocator,
                          V2CopyFromV1BufferMemorySettings(allocator, v1.buffer_settings));
  if (v1.has_image_format_constraints) {
    auto image_format_constraints_result =
        V2CopyFromV1ImageFormatConstraints(allocator, v1.image_format_constraints);
    if (!image_format_constraints_result.is_ok()) {
      LOG(ERROR, "!image_format_constraints_result.is_ok()");
      return fit::error();
    }
    v2b.set_image_format_constraints(allocator, image_format_constraints_result.take_value());
  }
  return fit::ok(std::move(v2b));
}

fuchsia_sysmem2::wire::VmoBuffer V2MoveFromV1VmoBuffer(
    fidl::AnyAllocator& allocator, fuchsia_sysmem::wire::VmoBuffer&& to_move_v1) {
  fuchsia_sysmem::wire::VmoBuffer v1 = std::move(to_move_v1);
  fuchsia_sysmem2::wire::VmoBuffer v2b(allocator);
  if (v1.vmo) {
    v2b.set_vmo(allocator, std::move(v1.vmo));
  }
  PROCESS_SCALAR_FIELD_V1(vmo_usable_start);
  ZX_DEBUG_ASSERT(!v2b.has_aux_vmo());
  return v2b;
}

fit::result<fuchsia_sysmem2::wire::BufferCollectionInfo> V2MoveFromV1BufferCollectionInfo(
    fidl::AnyAllocator& allocator, fuchsia_sysmem::wire::BufferCollectionInfo_2&& to_move_v1) {
  fuchsia_sysmem::wire::BufferCollectionInfo_2 v1 = std::move(to_move_v1);
  fuchsia_sysmem2::wire::BufferCollectionInfo v2b(allocator);
  auto settings_result = V2CopyFromV1SingleBufferSettings(allocator, v1.settings);
  if (!settings_result.is_ok()) {
    LOG(ERROR, "!settings_result.is_ok()");
    return fit::error();
  }
  v2b.set_settings(allocator, settings_result.take_value());
  if (v1.buffer_count) {
    v2b.set_buffers(allocator, allocator, v1.buffer_count);
    for (uint32_t i = 0; i < v1.buffer_count; ++i) {
      v2b.buffers()[i] = V2MoveFromV1VmoBuffer(allocator, std::move(v1.buffers[i]));
    }
  }
  return fit::ok(std::move(v2b));
}

fit::result<std::pair<std::optional<fuchsia_sysmem::wire::BufferCollectionConstraints>,
                      std::optional<fuchsia_sysmem::wire::BufferCollectionConstraintsAuxBuffers>>>
V1CopyFromV2BufferCollectionConstraints(
    const fuchsia_sysmem2::wire::BufferCollectionConstraints& v2) {
  fuchsia_sysmem::wire::BufferCollectionConstraints v1{};
  if (v2.IsEmpty()) {
    return fit::ok(
        std::pair<std::optional<fuchsia_sysmem::wire::BufferCollectionConstraints>,
                  std::optional<fuchsia_sysmem::wire::BufferCollectionConstraintsAuxBuffers>>());
  }
  if (v2.has_usage()) {
    v1.usage = V1CopyFromV2BufferUsage(v2.usage());
  }
  PROCESS_SCALAR_FIELD_V2(min_buffer_count_for_camping);
  PROCESS_SCALAR_FIELD_V2(min_buffer_count_for_dedicated_slack);
  PROCESS_SCALAR_FIELD_V2(min_buffer_count_for_shared_slack);
  PROCESS_SCALAR_FIELD_V2(min_buffer_count);
  PROCESS_SCALAR_FIELD_V2(max_buffer_count);
  ZX_DEBUG_ASSERT(!v1.has_buffer_memory_constraints);
  if (v2.has_buffer_memory_constraints()) {
    v1.has_buffer_memory_constraints = true;
    auto buffer_memory_constraints_result =
        V1CopyFromV2BufferMemoryConstraints(v2.buffer_memory_constraints());
    if (!buffer_memory_constraints_result.is_ok()) {
      LOG(ERROR, "!buffer_memory_constraints_result.is_ok()");
      return fit::error();
    }
    v1.buffer_memory_constraints = buffer_memory_constraints_result.take_value();
  }
  ZX_DEBUG_ASSERT(!v1.image_format_constraints_count);
  if (v2.has_image_format_constraints()) {
    if (v2.image_format_constraints().count() >
        fuchsia_sysmem::wire::MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS) {
      LOG(ERROR,
          "v2 image_format_constraints count > v1 "
          "MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS");
      return fit::error();
    }
    v1.image_format_constraints_count = v2.image_format_constraints().count();
    for (uint32_t i = 0; i < v2.image_format_constraints().count(); ++i) {
      auto image_format_constraints_result =
          V1CopyFromV2ImageFormatConstraints(v2.image_format_constraints()[i]);
      if (!image_format_constraints_result.is_ok()) {
        LOG(ERROR, "!image_format_constraints_result.is_ok()");
        return fit::error();
      }
      v1.image_format_constraints[i] = image_format_constraints_result.take_value();
    }
  }

  std::optional<fuchsia_sysmem::wire::BufferCollectionConstraintsAuxBuffers> v1_aux_buffers;
  if (v2.has_need_clear_aux_buffers_for_secure() || v2.has_allow_clear_aux_buffers_for_secure()) {
    fuchsia_sysmem::wire::BufferCollectionConstraintsAuxBuffers v1{};
    PROCESS_SCALAR_FIELD_V2(need_clear_aux_buffers_for_secure);
    PROCESS_SCALAR_FIELD_V2(allow_clear_aux_buffers_for_secure);
    v1_aux_buffers.emplace(v1);
  }

  return fit::ok(std::make_pair(std::move(v1), std::move(v1_aux_buffers)));
}

fit::result<fuchsia_sysmem::wire::BufferMemoryConstraints> V1CopyFromV2BufferMemoryConstraints(
    const fuchsia_sysmem2::wire::BufferMemoryConstraints& v2) {
  fuchsia_sysmem::wire::BufferMemoryConstraints v1{};
  PROCESS_SCALAR_FIELD_V2(min_size_bytes);
  PROCESS_SCALAR_FIELD_V2(max_size_bytes);
  PROCESS_SCALAR_FIELD_V2(physically_contiguous_required);
  PROCESS_SCALAR_FIELD_V2(secure_required);
  PROCESS_SCALAR_FIELD_V2(ram_domain_supported);
  PROCESS_SCALAR_FIELD_V2(cpu_domain_supported);
  PROCESS_SCALAR_FIELD_V2(inaccessible_domain_supported);
  ZX_DEBUG_ASSERT(!v1.heap_permitted_count);
  if (v2.has_heap_permitted()) {
    if (v2.heap_permitted().count() >
        fuchsia_sysmem::wire::MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_HEAP_PERMITTED) {
      LOG(ERROR, "v2 heap_permitted count > v1 MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_HEAP_PERMITTED");
      return fit::error();
    }
    v1.heap_permitted_count = v2.heap_permitted().count();
    for (uint32_t i = 0; i < v2.heap_permitted().count(); ++i) {
      ASSIGN_SCALAR(v1.heap_permitted[i], v2.heap_permitted()[i]);
    }
  }
  return fit::ok(std::move(v1));
}

fuchsia_sysmem::wire::BufferUsage V1CopyFromV2BufferUsage(
    const fuchsia_sysmem2::wire::BufferUsage& v2) {
  fuchsia_sysmem::wire::BufferUsage v1{};
  PROCESS_SCALAR_FIELD_V2(none);
  PROCESS_SCALAR_FIELD_V2(cpu);
  PROCESS_SCALAR_FIELD_V2(vulkan);
  PROCESS_SCALAR_FIELD_V2(display);
  PROCESS_SCALAR_FIELD_V2(video);
  return v1;
}

// v2 must have all fields set.
fuchsia_sysmem::wire::BufferMemorySettings V1CopyFromV2BufferMemorySettings(
    const fuchsia_sysmem2::wire::BufferMemorySettings& v2) {
  fuchsia_sysmem::wire::BufferMemorySettings v1{};
  PROCESS_SCALAR_FIELD_V2(size_bytes);
  PROCESS_SCALAR_FIELD_V2(is_physically_contiguous);
  PROCESS_SCALAR_FIELD_V2(is_secure);
  PROCESS_SCALAR_FIELD_V2(coherency_domain);
  PROCESS_SCALAR_FIELD_V2(heap);
  return v1;
}

fuchsia_sysmem::wire::PixelFormat V1CopyFromV2PixelFormat(
    const fuchsia_sysmem2::wire::PixelFormat& v2) {
  fuchsia_sysmem::wire::PixelFormat v1;
  PROCESS_SCALAR_FIELD_V2(type);
  v1.has_format_modifier = v2.has_format_modifier_value();
  if (v2.has_format_modifier_value()) {
    v1.format_modifier.value = v2.format_modifier_value();
  }
  return v1;
}

fuchsia_sysmem::wire::ColorSpace V1CopyFromV2ColorSpace(
    const fuchsia_sysmem2::wire::ColorSpace& v2) {
  fuchsia_sysmem::wire::ColorSpace v1{};
  PROCESS_SCALAR_FIELD_V2(type);
  return v1;
}

fit::result<fuchsia_sysmem::wire::ImageFormatConstraints> V1CopyFromV2ImageFormatConstraints(
    const fuchsia_sysmem2::wire::ImageFormatConstraints& v2) {
  fuchsia_sysmem::wire::ImageFormatConstraints v1;
  v1.pixel_format = V1CopyFromV2PixelFormat(v2.pixel_format());
  ZX_DEBUG_ASSERT(!v1.color_spaces_count);
  if (v2.has_color_spaces()) {
    if (v2.color_spaces().count() >
        fuchsia_sysmem::wire::MAX_COUNT_IMAGE_FORMAT_CONSTRAINTS_COLOR_SPACES) {
      LOG(ERROR,
          "v2.color_spaces().count() > "
          "fuchsia_sysmem::wire::MAX_COUNT_IMAGE_FORMAT_CONSTRAINTS_COLOR_SPACES");
      return fit::error();
    }
    v1.color_spaces_count = v2.color_spaces().count();
    for (uint32_t i = 0; i < v2.color_spaces().count(); ++i) {
      v1.color_space[i] = V1CopyFromV2ColorSpace(v2.color_spaces()[i]);
    }
  }
  PROCESS_SCALAR_FIELD_V2(min_coded_width);
  PROCESS_SCALAR_FIELD_V2(max_coded_width);
  PROCESS_SCALAR_FIELD_V2(min_coded_height);
  PROCESS_SCALAR_FIELD_V2(max_coded_height);
  PROCESS_SCALAR_FIELD_V2(min_bytes_per_row);
  PROCESS_SCALAR_FIELD_V2(max_bytes_per_row);
  PROCESS_SCALAR_FIELD_V2(max_coded_width_times_coded_height);
  v1.layers = 1;
  PROCESS_SCALAR_FIELD_V2(coded_width_divisor);
  PROCESS_SCALAR_FIELD_V2(coded_height_divisor);
  PROCESS_SCALAR_FIELD_V2(bytes_per_row_divisor);
  PROCESS_SCALAR_FIELD_V2(start_offset_divisor);
  PROCESS_SCALAR_FIELD_V2(display_width_divisor);
  PROCESS_SCALAR_FIELD_V2(display_height_divisor);
  PROCESS_SCALAR_FIELD_V2(required_min_coded_width);
  PROCESS_SCALAR_FIELD_V2(required_max_coded_width);
  PROCESS_SCALAR_FIELD_V2(required_min_coded_height);
  PROCESS_SCALAR_FIELD_V2(required_max_coded_height);
  PROCESS_SCALAR_FIELD_V2(required_min_bytes_per_row);
  PROCESS_SCALAR_FIELD_V2(required_max_bytes_per_row);
  return fit::ok(std::move(v1));
}

fit::result<fuchsia_sysmem::wire::ImageFormat_2> V1CopyFromV2ImageFormat(
    fuchsia_sysmem2::wire::ImageFormat& v2) {
  fuchsia_sysmem::wire::ImageFormat_2 v1;
  if (v2.has_pixel_format()) {
    v1.pixel_format = V1CopyFromV2PixelFormat(v2.pixel_format());
  }
  PROCESS_SCALAR_FIELD_V2(coded_width);
  PROCESS_SCALAR_FIELD_V2(coded_height);
  PROCESS_SCALAR_FIELD_V2(bytes_per_row);
  PROCESS_SCALAR_FIELD_V2(display_width);
  PROCESS_SCALAR_FIELD_V2(display_height);
  v1.layers = 1;
  if (v2.has_color_space()) {
    v1.color_space = V1CopyFromV2ColorSpace(v2.color_space());
  }
  v1.has_pixel_aspect_ratio =
      v2.has_pixel_aspect_ratio_width() && v2.has_pixel_aspect_ratio_height() ? true : false;
  if (v1.has_pixel_aspect_ratio) {
    v1.pixel_aspect_ratio_width = v2.pixel_aspect_ratio_width();
    v1.pixel_aspect_ratio_height = v2.pixel_aspect_ratio_height();
  }
  return fit::ok(std::move(v1));
}

fit::result<fuchsia_sysmem::wire::SingleBufferSettings> V1CopyFromV2SingleBufferSettings(
    const fuchsia_sysmem2::wire::SingleBufferSettings& v2) {
  fuchsia_sysmem::wire::SingleBufferSettings v1;
  v1.buffer_settings = V1CopyFromV2BufferMemorySettings(v2.buffer_settings());
  v1.has_image_format_constraints = v2.has_image_format_constraints();
  if (v2.has_image_format_constraints()) {
    auto image_format_constraints_result =
        V1CopyFromV2ImageFormatConstraints(v2.image_format_constraints());
    if (!image_format_constraints_result.is_ok()) {
      LOG(ERROR, "!image_format_constraints_result.is_ok()");
      return fit::error();
    }
    v1.image_format_constraints = image_format_constraints_result.take_value();
  }
  return fit::ok(std::move(v1));
}

// Intentionally just consumes aux_vmo.  The implied extra handle duplications from this behavior go
// away when all participants speak V2.  For V1 participants that need the aux_vmo, there's a
// completely different method and struct for getting that.
fuchsia_sysmem::wire::VmoBuffer V1MoveFromV2VmoBuffer(
    fuchsia_sysmem2::wire::VmoBuffer&& to_move_v2) {
  // Always take ownership even on failure.
  fuchsia_sysmem2::wire::VmoBuffer v2 = std::move(to_move_v2);
  fuchsia_sysmem::wire::VmoBuffer v1;
  if (v2.has_vmo()) {
    v1.vmo = std::move(v2.vmo());
  }
  PROCESS_SCALAR_FIELD_V2(vmo_usable_start);
  // ~v2 will ~aux_vmo, intentionally - see function comment above.
  return v1;
}

// Intentionally just consumes vmo (but not aux_vmo).  The implied extra handle duplications from
// this behavior go away when all participants speak V2.
fuchsia_sysmem::wire::VmoBuffer V1AuxBuffersMoveFromV2VmoBuffer(
    fuchsia_sysmem2::wire::VmoBuffer&& to_move_v2) {
  // Always take ownership even on failure.
  fuchsia_sysmem2::wire::VmoBuffer v2 = std::move(to_move_v2);
  fuchsia_sysmem::wire::VmoBuffer v1;
  if (v2.has_aux_vmo()) {
    v1.vmo = std::move(v2.aux_vmo());
  }
  PROCESS_SCALAR_FIELD_V2(vmo_usable_start);
  // ~v2 will ~vmo, intentionally - see function comment above.
  return v1;
}

fit::result<fuchsia_sysmem::wire::BufferCollectionInfo_2> V1MoveFromV2BufferCollectionInfo(
    fuchsia_sysmem2::wire::BufferCollectionInfo&& to_move_v2) {
  // This move is mainly to make it very clear what's going on here, but also to ensure that we
  // don't take any dependency on incorrect/stale failure to move out any of the handles in to_move.
  //
  // Always take ownership of the incoming handles, even on failure.
  fuchsia_sysmem2::wire::BufferCollectionInfo v2 = std::move(to_move_v2);
  fuchsia_sysmem::wire::BufferCollectionInfo_2 v1;
  if (v2.has_buffers()) {
    if (v2.buffers().count() > fuchsia_sysmem::wire::MAX_COUNT_BUFFER_COLLECTION_INFO_BUFFERS) {
      LOG(ERROR,
          "v2.buffers().count() > "
          "fuchsia_sysmem::wire::MAX_COUNT_BUFFER_COLLECTION_INFO_BUFFERS");
      return fit::error();
    }
    v1.buffer_count = v2.buffers().count();
    for (uint32_t i = 0; i < v2.buffers().count(); ++i) {
      v1.buffers[i] = V1MoveFromV2VmoBuffer(std::move(v2.buffers()[i]));
    }
  }
  auto settings_result = V1CopyFromV2SingleBufferSettings(v2.settings());
  if (!settings_result.is_ok()) {
    LOG(ERROR, "!settings_result.is_ok()");
    return fit::error();
  }
  v1.settings = settings_result.take_value();
  return fit::ok(std::move(v1));
}

[[nodiscard]] fit::result<fuchsia_sysmem::wire::BufferCollectionInfo_2>
V1AuxBuffersMoveFromV2BufferCollectionInfo(
    fuchsia_sysmem2::wire::BufferCollectionInfo&& to_move_v2) {
  // This move is mainly to make it very clear what's going on here, but also to ensure that we
  // don't take any dependency on incorrect/stale failure to move out any of the handles in to_move.
  //
  // Always take ownership of the incoming handles, even on failure.
  fuchsia_sysmem2::wire::BufferCollectionInfo v2 = std::move(to_move_v2);
  fuchsia_sysmem::wire::BufferCollectionInfo_2 v1;
  if (v2.has_buffers()) {
    if (v2.buffers().count() > fuchsia_sysmem::wire::MAX_COUNT_BUFFER_COLLECTION_INFO_BUFFERS) {
      LOG(ERROR,
          "v2.buffers().count() > "
          "fuchsia_sysmem::wire::MAX_COUNT_BUFFER_COLLECTION_INFO_BUFFERS");
      return fit::error();
    }
    v1.buffer_count = v2.buffers().count();
    for (uint32_t i = 0; i < v2.buffers().count(); ++i) {
      v1.buffers[i] = V1AuxBuffersMoveFromV2VmoBuffer(std::move(v2.buffers()[i]));
    }
  }
  auto settings_result = V1CopyFromV2SingleBufferSettings(v2.settings());
  if (!settings_result.is_ok()) {
    LOG(ERROR, "!settings_result.is_ok()");
    return fit::error();
  }
  v1.settings = settings_result.take_value();
  return fit::ok(std::move(v1));
}

fuchsia_sysmem2::wire::PixelFormat V2ClonePixelFormat(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::PixelFormat& src) {
  fuchsia_sysmem2::wire::PixelFormat pixel_format(allocator);
  if (src.has_type()) {
    pixel_format.set_type(allocator, src.type());
  }
  if (src.has_format_modifier_value()) {
    pixel_format.set_format_modifier_value(allocator, src.format_modifier_value());
  }
  return pixel_format;
}

fuchsia_sysmem2::wire::ColorSpace V2CloneColorSpace(fidl::AnyAllocator& allocator,
                                                    const fuchsia_sysmem2::wire::ColorSpace& src) {
  fuchsia_sysmem2::wire::ColorSpace color_space(allocator);
  if (src.has_type()) {
    color_space.set_type(allocator, src.type());
  }
  return color_space;
}

fuchsia_sysmem2::wire::BufferMemorySettings V2CloneBufferMemorySettings(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::BufferMemorySettings& src) {
  fuchsia_sysmem2::wire::BufferMemorySettings buffer_memory_settings(allocator);
  if (src.has_size_bytes()) {
    buffer_memory_settings.set_size_bytes(allocator, src.size_bytes());
  }
  if (src.has_is_physically_contiguous()) {
    buffer_memory_settings.set_is_physically_contiguous(allocator, src.is_physically_contiguous());
  }
  if (src.has_is_secure()) {
    buffer_memory_settings.set_is_secure(allocator, src.is_secure());
  }
  if (src.has_coherency_domain()) {
    buffer_memory_settings.set_coherency_domain(allocator, src.coherency_domain());
  }
  if (src.has_heap()) {
    buffer_memory_settings.set_heap(allocator, src.heap());
  }
  return buffer_memory_settings;
}

fuchsia_sysmem2::wire::ImageFormatConstraints V2CloneImageFormatConstraints(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::ImageFormatConstraints& src) {
  fuchsia_sysmem2::wire::ImageFormatConstraints image_format_constraints(allocator);
  if (src.has_pixel_format()) {
    image_format_constraints.set_pixel_format(allocator,
                                              V2ClonePixelFormat(allocator, src.pixel_format()));
  }
  if (src.has_color_spaces()) {
    image_format_constraints.set_color_spaces(allocator, allocator, src.color_spaces().count());
    for (uint32_t i = 0; i < src.color_spaces().count(); ++i) {
      image_format_constraints.color_spaces()[i] =
          V2CloneColorSpace(allocator, src.color_spaces()[i]);
    }
  }
  if (src.has_min_coded_width()) {
    image_format_constraints.set_min_coded_width(allocator, src.min_coded_width());
  }
  if (src.has_max_coded_width()) {
    image_format_constraints.set_max_coded_width(allocator, src.max_coded_width());
  }
  if (src.has_min_coded_height()) {
    image_format_constraints.set_min_coded_height(allocator, src.min_coded_height());
  }
  if (src.has_max_coded_height()) {
    image_format_constraints.set_max_coded_height(allocator, src.max_coded_height());
  }
  if (src.has_min_bytes_per_row()) {
    image_format_constraints.set_min_bytes_per_row(allocator, src.min_bytes_per_row());
  }
  if (src.has_max_bytes_per_row()) {
    image_format_constraints.set_max_bytes_per_row(allocator, src.max_bytes_per_row());
  }
  if (src.has_max_coded_width_times_coded_height()) {
    image_format_constraints.set_max_coded_width_times_coded_height(
        allocator, src.max_coded_width_times_coded_height());
  }
  if (src.has_coded_width_divisor()) {
    image_format_constraints.set_coded_width_divisor(allocator, src.coded_width_divisor());
  }
  if (src.has_coded_height_divisor()) {
    image_format_constraints.set_coded_height_divisor(allocator, src.coded_height_divisor());
  }
  if (src.has_bytes_per_row_divisor()) {
    image_format_constraints.set_bytes_per_row_divisor(allocator, src.bytes_per_row_divisor());
  }
  if (src.has_start_offset_divisor()) {
    image_format_constraints.set_start_offset_divisor(allocator, src.start_offset_divisor());
  }
  if (src.has_display_width_divisor()) {
    image_format_constraints.set_display_width_divisor(allocator, src.display_width_divisor());
  }
  if (src.has_display_height_divisor()) {
    image_format_constraints.set_display_height_divisor(allocator, src.display_height_divisor());
  }
  if (src.has_required_min_coded_width()) {
    image_format_constraints.set_required_min_coded_width(allocator,
                                                          src.required_min_coded_width());
  }
  if (src.has_required_max_coded_width()) {
    image_format_constraints.set_required_max_coded_width(allocator,
                                                          src.required_max_coded_width());
  }
  if (src.has_required_min_coded_height()) {
    image_format_constraints.set_required_min_coded_height(allocator,
                                                           src.required_min_coded_height());
  }
  if (src.has_required_max_coded_height()) {
    image_format_constraints.set_required_max_coded_height(allocator,
                                                           src.required_max_coded_height());
  }
  if (src.has_required_min_bytes_per_row()) {
    image_format_constraints.set_required_min_bytes_per_row(allocator,
                                                            src.required_min_bytes_per_row());
  }
  if (src.has_required_max_bytes_per_row()) {
    image_format_constraints.set_required_max_bytes_per_row(allocator,
                                                            src.required_max_bytes_per_row());
  }
  return image_format_constraints;
}

fuchsia_sysmem2::wire::SingleBufferSettings V2CloneSingleBufferSettings(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::SingleBufferSettings& src) {
  fuchsia_sysmem2::wire::SingleBufferSettings single_buffer_settings(allocator);
  if (src.has_buffer_settings()) {
    single_buffer_settings.set_buffer_settings(
        allocator, V2CloneBufferMemorySettings(allocator, src.buffer_settings()));
  }
  if (src.has_image_format_constraints()) {
    single_buffer_settings.set_image_format_constraints(
        allocator, V2CloneImageFormatConstraints(allocator, src.image_format_constraints()));
  }
  return single_buffer_settings;
}

fit::result<fuchsia_sysmem2::wire::VmoBuffer, zx_status_t> V2CloneVmoBuffer(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::VmoBuffer& src,
    uint32_t vmo_rights_mask, uint32_t aux_vmo_rights_mask) {
  fuchsia_sysmem2::wire::VmoBuffer vmo_buffer(allocator);
  if (src.has_vmo()) {
    zx::vmo clone_vmo;
    if (src.vmo().get() != ZX_HANDLE_INVALID) {
      zx_info_handle_basic_t info{};
      zx_status_t get_info_status =
          src.vmo().get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
      if (get_info_status != ZX_OK) {
        LOG(ERROR, "get_info_status: %d", get_info_status);
        return fit::error(get_info_status);
      }
      zx_status_t duplicate_status = src.vmo().duplicate(info.rights & vmo_rights_mask, &clone_vmo);
      if (duplicate_status != ZX_OK) {
        LOG(ERROR, "duplicate_status: %d", duplicate_status);
        return fit::error(duplicate_status);
      }
    } else {
      ZX_DEBUG_ASSERT(clone_vmo.get() == ZX_HANDLE_INVALID);
    }
    vmo_buffer.set_vmo(allocator, std::move(clone_vmo));
  }
  if (src.has_vmo_usable_start()) {
    vmo_buffer.set_vmo_usable_start(allocator, src.vmo_usable_start());
  }
  if (src.has_aux_vmo()) {
    zx::vmo clone_vmo;
    if (src.aux_vmo().get() != ZX_HANDLE_INVALID) {
      zx_info_handle_basic_t info{};
      zx_status_t get_info_status =
          src.aux_vmo().get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
      if (get_info_status != ZX_OK) {
        LOG(ERROR, "get_info_status: %d", get_info_status);
        return fit::error(get_info_status);
      }
      zx_status_t duplicate_status =
          src.aux_vmo().duplicate(info.rights & aux_vmo_rights_mask, &clone_vmo);
      if (duplicate_status != ZX_OK) {
        LOG(ERROR, "duplicate_status: %d", duplicate_status);
        return fit::error(duplicate_status);
      }
    } else {
      ZX_DEBUG_ASSERT(clone_vmo.get() == ZX_HANDLE_INVALID);
    }
    vmo_buffer.set_aux_vmo(allocator, std::move(clone_vmo));
  }
  return fit::ok(std::move(vmo_buffer));
}

fit::result<fuchsia_sysmem2::wire::BufferCollectionInfo, zx_status_t> V2CloneBufferCollectionInfo(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::BufferCollectionInfo& src,
    uint32_t vmo_rights_mask, uint32_t aux_vmo_rights_mask) {
  fuchsia_sysmem2::wire::BufferCollectionInfo buffer_collection_info(allocator);
  if (src.has_settings()) {
    buffer_collection_info.set_settings(allocator,
                                        V2CloneSingleBufferSettings(allocator, src.settings()));
  }
  if (src.has_buffers()) {
    buffer_collection_info.set_buffers(allocator, allocator, src.buffers().count());
    for (uint32_t i = 0; i < src.buffers().count(); ++i) {
      auto clone_result =
          V2CloneVmoBuffer(allocator, src.buffers()[i], vmo_rights_mask, aux_vmo_rights_mask);
      if (!clone_result.is_ok()) {
        return clone_result.take_error_result();
      }
      buffer_collection_info.buffers()[i] = clone_result.take_value();
    }
  }
  return fit::ok(std::move(buffer_collection_info));
}

fuchsia_sysmem2::wire::CoherencyDomainSupport V2CloneCoherencyDomainSuppoort(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::CoherencyDomainSupport& src) {
  fuchsia_sysmem2::wire::CoherencyDomainSupport coherency_domain_support(allocator);
  if (src.has_cpu_supported()) {
    coherency_domain_support.set_cpu_supported(allocator, src.cpu_supported());
  }
  if (src.has_ram_supported()) {
    coherency_domain_support.set_ram_supported(allocator, src.ram_supported());
  }
  if (src.has_inaccessible_supported()) {
    coherency_domain_support.set_inaccessible_supported(allocator, src.inaccessible_supported());
  }
  return coherency_domain_support;
}

fuchsia_sysmem2::wire::HeapProperties V2CloneHeapProperties(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::HeapProperties& src) {
  fuchsia_sysmem2::wire::HeapProperties heap_properties(allocator);
  if (src.has_coherency_domain_support()) {
    heap_properties.set_coherency_domain_support(
        allocator, V2CloneCoherencyDomainSuppoort(allocator, src.coherency_domain_support()));
  }
  if (src.has_need_clear()) {
    heap_properties.set_need_clear(allocator, src.need_clear());
  }
  return heap_properties;
}

fuchsia_sysmem2::wire::BufferCollectionConstraints V2CloneBufferCollectionConstraints(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::BufferCollectionConstraints& src) {
  fuchsia_sysmem2::wire::BufferCollectionConstraints buffer_collection_constraints(allocator);
  if (src.has_usage()) {
    buffer_collection_constraints.set_usage(allocator, V2CloneBufferUsage(allocator, src.usage()));
  }
  if (src.has_min_buffer_count_for_camping()) {
    buffer_collection_constraints.set_min_buffer_count_for_camping(
        allocator, src.min_buffer_count_for_camping());
  }
  if (src.has_min_buffer_count_for_dedicated_slack()) {
    buffer_collection_constraints.set_min_buffer_count_for_dedicated_slack(
        allocator, src.min_buffer_count_for_dedicated_slack());
  }
  if (src.has_min_buffer_count_for_shared_slack()) {
    buffer_collection_constraints.set_min_buffer_count_for_shared_slack(
        allocator, src.min_buffer_count_for_shared_slack());
  }
  if (src.has_min_buffer_count()) {
    buffer_collection_constraints.set_min_buffer_count(allocator, src.min_buffer_count());
  }
  if (src.has_max_buffer_count()) {
    buffer_collection_constraints.set_max_buffer_count(allocator, src.max_buffer_count());
  }
  if (src.has_buffer_memory_constraints()) {
    buffer_collection_constraints.set_buffer_memory_constraints(
        allocator, V2CloneBufferMemoryConstraints(allocator, src.buffer_memory_constraints()));
  }
  if (src.has_image_format_constraints()) {
    buffer_collection_constraints.set_image_format_constraints(
        allocator, allocator, src.image_format_constraints().count());
    for (uint32_t i = 0; i < src.image_format_constraints().count(); ++i) {
      buffer_collection_constraints.image_format_constraints()[i] =
          V2CloneImageFormatConstraints(allocator, src.image_format_constraints()[i]);
    }
  }
  if (src.has_need_clear_aux_buffers_for_secure()) {
    buffer_collection_constraints.set_need_clear_aux_buffers_for_secure(
        allocator, src.need_clear_aux_buffers_for_secure());
  }
  if (src.has_allow_clear_aux_buffers_for_secure()) {
    buffer_collection_constraints.set_allow_clear_aux_buffers_for_secure(
        allocator, src.allow_clear_aux_buffers_for_secure());
  }
  return buffer_collection_constraints;
}

fuchsia_sysmem2::wire::BufferUsage V2CloneBufferUsage(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::BufferUsage& src) {
  fuchsia_sysmem2::wire::BufferUsage buffer_usage(allocator);
  if (src.has_none()) {
    buffer_usage.set_none(allocator, src.none());
  }
  if (src.has_cpu()) {
    buffer_usage.set_cpu(allocator, src.cpu());
  }
  if (src.has_vulkan()) {
    buffer_usage.set_vulkan(allocator, src.vulkan());
  }
  if (src.has_display()) {
    buffer_usage.set_display(allocator, src.display());
  }
  if (src.has_video()) {
    buffer_usage.set_video(allocator, src.video());
  }
  return buffer_usage;
}

fuchsia_sysmem2::wire::BufferMemoryConstraints V2CloneBufferMemoryConstraints(
    fidl::AnyAllocator& allocator, const fuchsia_sysmem2::wire::BufferMemoryConstraints& src) {
  fuchsia_sysmem2::wire::BufferMemoryConstraints buffer_memory_constraints(allocator);
  if (src.has_min_size_bytes()) {
    buffer_memory_constraints.set_min_size_bytes(allocator, src.min_size_bytes());
  }
  if (src.has_max_size_bytes()) {
    buffer_memory_constraints.set_max_size_bytes(allocator, src.max_size_bytes());
  }
  if (src.has_physically_contiguous_required()) {
    buffer_memory_constraints.set_physically_contiguous_required(
        allocator, src.physically_contiguous_required());
  }
  if (src.has_secure_required()) {
    buffer_memory_constraints.set_secure_required(allocator, src.secure_required());
  }
  if (src.has_cpu_domain_supported()) {
    buffer_memory_constraints.set_cpu_domain_supported(allocator, src.cpu_domain_supported());
  }
  if (src.has_ram_domain_supported()) {
    buffer_memory_constraints.set_ram_domain_supported(allocator, src.ram_domain_supported());
  }
  if (src.has_inaccessible_domain_supported()) {
    buffer_memory_constraints.set_inaccessible_domain_supported(
        allocator, src.inaccessible_domain_supported());
  }
  if (src.has_heap_permitted()) {
    buffer_memory_constraints.set_heap_permitted(allocator, allocator,
                                                 src.heap_permitted().count());
    ZX_DEBUG_ASSERT(buffer_memory_constraints.heap_permitted().count() ==
                    src.heap_permitted().count());
    for (uint32_t i = 0; i < src.heap_permitted().count(); ++i) {
      buffer_memory_constraints.heap_permitted()[i] = src.heap_permitted()[i];
    }
  }
  return buffer_memory_constraints;
}

}  // namespace sysmem
