// 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/llcpp/coding.h>
#include <lib/fidl/llcpp/errors.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/server.h>
#include <stdio.h>

namespace fidl {

OutgoingMessage::OutgoingMessage(uint8_t* bytes, uint32_t byte_capacity, uint32_t byte_actual,
                                 zx_handle_t* handles, uint32_t handle_capacity,
                                 uint32_t handle_actual)
    : ::fidl::Result(ZX_OK, nullptr),
      message_{.bytes = bytes,
               .handles = handles,
               .num_bytes = byte_actual,
               .num_handles = handle_actual},
      byte_capacity_(byte_capacity),
      handle_capacity_(handle_capacity) {
  if (byte_capacity < byte_actual) {
    SetResult(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::kErrorRequestBufferTooSmall);
  }
}

OutgoingMessage::~OutgoingMessage() {
  if (handle_actual() > 0) {
    zx_handle_close_many(handles(), handle_actual());
  }
}

void OutgoingMessage::LinearizeAndEncode(const fidl_type_t* message_type, void* data) {
  if (status_ == ZX_OK) {
    uint32_t num_bytes_actual;
    uint32_t num_handles_actual;
    status_ = fidl_linearize_and_encode(message_type, data, bytes(), byte_capacity(),
                                        message_.handles, handle_capacity(), &num_bytes_actual,
                                        &num_handles_actual, &error_);
    if (status_ == ZX_OK) {
      message_.num_bytes = num_bytes_actual;
      message_.num_handles = num_handles_actual;
    }
  }
}

void OutgoingMessage::Write(zx_handle_t channel) {
  if (status_ != ZX_OK) {
    return;
  }
  status_ = zx_channel_write(channel, 0, bytes(), byte_actual(), handles(), handle_actual());
  if (status_ != ZX_OK) {
    error_ = ::fidl::kErrorWriteFailed;
  }
  ReleaseHandles();
}

void OutgoingMessage::Call(const fidl_type_t* response_type, zx_handle_t channel,
                           uint8_t* result_bytes, uint32_t result_capacity, zx_time_t deadline) {
  if (status_ != ZX_OK) {
    return;
  }
  zx_handle_t result_handles[ZX_CHANNEL_MAX_MSG_HANDLES];
  uint32_t actual_num_bytes = 0u;
  uint32_t actual_num_handles = 0u;
  zx_channel_call_args_t args = {.wr_bytes = bytes(),
                                 .wr_handles = handles(),
                                 .rd_bytes = result_bytes,
                                 .rd_handles = result_handles,
                                 .wr_num_bytes = byte_actual(),
                                 .wr_num_handles = handle_actual(),
                                 .rd_num_bytes = result_capacity,
                                 .rd_num_handles = ZX_CHANNEL_MAX_MSG_HANDLES};

  status_ = zx_channel_call(channel, 0u, deadline, &args, &actual_num_bytes, &actual_num_handles);
  if (status_ == ZX_OK) {
    status_ = fidl_decode(response_type, result_bytes, actual_num_bytes, result_handles,
                          actual_num_handles, &error_);
  } else {
    error_ = ::fidl::kErrorWriteFailed;
  }
  ReleaseHandles();
}

::fidl::Result OutgoingMessage::Write(::fidl::internal::ClientBase* client,
                                      ::fidl::internal::ResponseContext* context) {
  if (auto channel = client->GetChannel()) {
    Write(channel->handle());
  } else {
    status_ = ZX_ERR_CANCELED;
    error_ = ::fidl::kErrorChannelUnbound;
  }
  if (!ok()) {
    client->ForgetAsyncTxn(context);
    delete context;
  }
  return ::fidl::Result(status_, error_);
}

IncomingMessage::IncomingMessage(uint8_t* bytes, uint32_t byte_capacity, uint32_t byte_actual,
                                 zx_handle_t* handles, uint32_t handle_capacity,
                                 uint32_t handle_actual)
    : ::fidl::Result(ZX_OK, nullptr),
      message_{.bytes = bytes,
               .handles = handles,
               .num_bytes = byte_actual,
               .num_handles = handle_actual},
      byte_capacity_(byte_capacity),
      handle_capacity_(handle_capacity) {
  if (byte_capacity < byte_actual) {
    SetResult(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::kErrorRequestBufferTooSmall);
  }
}

IncomingMessage::~IncomingMessage() {
  if (handle_actual() > 0) {
    zx_handle_close_many(handles(), handle_actual());
  }
}

void IncomingMessage::Decode(const fidl_type_t* message_type) {
  status_ = fidl_decode(message_type, bytes(), byte_actual(), handles(), handle_actual(), &error_);
  ReleaseHandles();
}

}  // namespace fidl
