// 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/coding.h>
#include <lib/fidl/cpp/builder.h>
#include <lib/fidl/cpp/message.h>
#include <string.h>

#ifdef __Fuchsia__
#include <zircon/syscalls.h>
#endif

namespace fidl {

Message::Message() = default;

Message::Message(BytePart bytes, HandlePart handles)
    : bytes_(static_cast<BytePart&&>(bytes)), handles_(static_cast<HandlePart&&>(handles)) {}

Message::~Message() {
#ifdef __Fuchsia__
  if (handles_.actual() > 0) {
    zx_handle_close_many(handles_.data(), handles_.actual());
  }
#endif
  ClearHandlesUnsafe();
}

Message::Message(Message&& other)
    : bytes_(static_cast<BytePart&&>(other.bytes_)),
      handles_(static_cast<HandlePart&&>(other.handles_)) {}

Message& Message::operator=(Message&& other) {
  bytes_ = static_cast<BytePart&&>(other.bytes_);
  handles_ = static_cast<HandlePart&&>(other.handles_);
  return *this;
}

zx_status_t Message::Encode(const fidl_type_t* type, const char** error_msg_out) {
  uint32_t actual_handles = 0u;
  zx_status_t status = fidl_encode(type, bytes_.data(), bytes_.actual(), handles_.data(),
                                   handles_.capacity(), &actual_handles, error_msg_out);
  if (status == ZX_OK)
    handles_.set_actual(actual_handles);
  return status;
}

zx_status_t Message::Decode(const fidl_type_t* type, const char** error_msg_out) {
  zx_status_t status = fidl_decode(type, bytes_.data(), bytes_.actual(), handles_.data(),
                                   handles_.actual(), error_msg_out);
  ClearHandlesUnsafe();
  return status;
}

zx_status_t Message::Validate(const fidl_type_t* type, const char** error_msg_out) const {
  return fidl_validate(type, bytes_.data(), bytes_.actual(), handles_.actual(), error_msg_out);
}

#ifdef __Fuchsia__
zx_status_t Message::Read(zx_handle_t channel, uint32_t flags) {
  uint32_t actual_bytes = 0u;
  uint32_t actual_handles = 0u;
  zx_status_t status =
      zx_channel_read(channel, flags, bytes_.data(), handles_.data(), bytes_.capacity(),
                      handles_.capacity(), &actual_bytes, &actual_handles);
  if (status == ZX_OK) {
    bytes_.set_actual(actual_bytes);
    handles_.set_actual(actual_handles);
  }
  return status;
}

zx_status_t Message::Write(zx_handle_t channel, uint32_t flags) {
  zx_status_t status = zx_channel_write(channel, flags, bytes_.data(), bytes_.actual(),
                                        handles_.data(), handles_.actual());
  ClearHandlesUnsafe();
  return status;
}

zx_status_t Message::Call(zx_handle_t channel, uint32_t flags, zx_time_t deadline,
                          Message* response) {
  zx_channel_call_args_t args;
  args.wr_bytes = bytes_.data();
  args.wr_handles = handles_.data();
  args.rd_bytes = response->bytes_.data();
  args.rd_handles = response->handles_.data();
  args.wr_num_bytes = bytes_.actual();
  args.wr_num_handles = handles_.actual();
  args.rd_num_bytes = response->bytes_.capacity();
  args.rd_num_handles = response->handles_.capacity();
  uint32_t actual_bytes = 0u;
  uint32_t actual_handles = 0u;
  zx_status_t status =
      zx_channel_call(channel, flags, deadline, &args, &actual_bytes, &actual_handles);
  ClearHandlesUnsafe();
  if (status == ZX_OK) {
    response->bytes_.set_actual(actual_bytes);
    response->handles_.set_actual(actual_handles);
  }
  return status;
}
#endif

void Message::ClearHandlesUnsafe() { handles_.set_actual(0u); }

}  // namespace fidl
