// 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/fidl/cpp/features.h>
#include <lib/fidl/cpp/wire/message.h>
#include <lib/fidl/internal.h>
#include <zircon/assert.h>
#include <zircon/errors.h>

#include <cstring>
#include <memory>
#include <string>

#if __FIDL_SUPPORT_HANDLES
#include <lib/fidl/cpp/wire/client_base.h>
#include <lib/fidl/cpp/wire/internal/transport_channel.h>
#include <lib/fidl/cpp/wire/server.h>
#include <zircon/syscalls.h>
#else
#include <lib/fidl/cpp/wire/internal/transport_channel_host.h>
#endif  // __FIDL_SUPPORT_HANDLES

namespace fidl {

OutgoingToEncodedMessage::OutgoingToEncodedMessage(OutgoingMessage& input)
    : encoded_message_(
          ConversionImpl(input, buf_bytes_, buf_handles_, buf_handle_metadata_, status_)) {}

[[nodiscard]] std::string OutgoingToEncodedMessage::FormatDescription() const {
  return status_.FormatDescription();
}

EncodedMessage OutgoingToEncodedMessage::ConversionImpl(
    OutgoingMessage& input, OutgoingMessage::CopiedBytes& buf_bytes,
    std::unique_ptr<zx_handle_t[]>& buf_handles,
    // TODO(https://fxbug.dev/42166666) Remove channel-specific logic.
    std::unique_ptr<fidl_channel_handle_metadata_t[]>& buf_handle_metadata,
    fidl::Status& out_status) {
  ZX_ASSERT(!input.is_transactional());

  zx_handle_t* handles = input.handles();
  fidl_channel_handle_metadata_t* handle_metadata =
      input.handle_metadata<fidl::internal::ChannelTransport>();
  uint32_t num_handles = input.handle_actual();
  input.ReleaseHandles();

  // Note: it may be possible to remove these allocations.
  buf_handles = std::make_unique<zx_handle_t[]>(num_handles);
  buf_handle_metadata = std::make_unique<fidl_channel_handle_metadata_t[]>(num_handles);
  for (uint32_t i = 0; i < num_handles; i++) {
    const char* error;
    zx_status_t status = FidlEnsureActualHandleRights(&handles[i], handle_metadata[i].obj_type,
                                                      handle_metadata[i].rights, &error);
    if (status != ZX_OK) {
      FidlHandleCloseMany(handles, num_handles);
      FidlHandleCloseMany(buf_handles.get(), num_handles);
      out_status = fidl::Status::EncodeError(status);
      return fidl::EncodedMessage::Create({});
    }
    buf_handles[i] = handles[i];
    buf_handle_metadata[i] = handle_metadata[i];
  }

  buf_bytes = input.CopyBytes();
  out_status = fidl::Status::Ok();
  return fidl::EncodedMessage::Create(cpp20::span<uint8_t>{buf_bytes}, buf_handles.get(),
                                      buf_handle_metadata.get(), num_handles);
}

}  // namespace fidl
