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

#include <string.h>

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