// Copyright 2017 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 <fidl/test/handles/cpp/fidl.h>
#include <lib/fidl/cpp/message.h>
#include <lib/zx/channel.h>
#include <lib/zx/event.h>

#include <zxtest/zxtest.h>

namespace {

TEST(Message, BasicTests) {
  uint8_t byte_buffer[ZX_CHANNEL_MAX_MSG_BYTES];
  zx_handle_info_t handle_info_buffer[ZX_CHANNEL_MAX_MSG_HANDLES];
  zx_handle_disposition_t handle_disposition_buffer[ZX_CHANNEL_MAX_MSG_HANDLES];

  fidl_message_header_t header = {
      .txid = 5u,
      .ordinal = 42u,
  };
  char data[4] = "abc";
  fidl_string_t str = {
      .size = 3,
      .data = data,
  };
  memcpy(byte_buffer, &header, sizeof(header));
  memcpy(byte_buffer + sizeof(header), &str, sizeof(str));
  memcpy(byte_buffer + sizeof(header) + sizeof(str), data, 3);
  memset(byte_buffer + sizeof(header) + sizeof(str), 0, 5);

  fidl::HLCPPOutgoingMessage outgoing_message(
      fidl::BytePart(byte_buffer, ZX_CHANNEL_MAX_MSG_BYTES, sizeof(header) + sizeof(str) + 8),
      fidl::HandleDispositionPart(handle_disposition_buffer, ZX_CHANNEL_MAX_MSG_HANDLES));

  EXPECT_EQ(outgoing_message.txid(), 5u);
  EXPECT_EQ(outgoing_message.ordinal(), 42u);

  fidl::BytePart payload = fidl::BytePart(outgoing_message.body_view().bytes(), 0);
  fidl_string_t* payload_str = reinterpret_cast<fidl_string_t*>(payload.data());
  EXPECT_EQ(3, payload_str->size);
  EXPECT_STREQ("abc", payload_str->data);

  zx::channel h1, h2;
  EXPECT_EQ(zx::channel::create(0, &h1, &h2), ZX_OK);

  ASSERT_EQ(ZX_OK, outgoing_message.Write(h1.get(), 0u));

  memset(byte_buffer, 0, ZX_CHANNEL_MAX_MSG_BYTES);

  EXPECT_EQ(outgoing_message.txid(), 0u);
  EXPECT_EQ(outgoing_message.ordinal(), 0u);

  fidl::HLCPPIncomingMessage incoming_message(
      fidl::BytePart(byte_buffer, ZX_CHANNEL_MAX_MSG_BYTES),
      fidl::HandleInfoPart(handle_info_buffer, ZX_CHANNEL_MAX_MSG_HANDLES));
  ASSERT_EQ(ZX_OK, incoming_message.Read(h2.get(), 0u));

  EXPECT_EQ(incoming_message.txid(), 5u);
  EXPECT_EQ(incoming_message.ordinal(), 42u);
}

TEST(Message, ReadErrorCodes) {
  // Create a Message buffer.
  constexpr size_t kBufferSize = 100;
  uint8_t byte_buffer[kBufferSize];
  fidl::HLCPPIncomingMessage message(fidl::BytePart::WrapEmpty(byte_buffer),
                                     fidl::HandleInfoPart());

  // Create a channel.
  zx::channel client, server;
  EXPECT_OK(zx::channel::create(0, &client, &server));

  // Read from an empty channel.
  EXPECT_EQ(message.Read(client.get(), /*flags=*/0), ZX_ERR_SHOULD_WAIT);

  // Read with invalid flags.
  EXPECT_EQ(message.Read(client.get(), /*flags=*/~0), ZX_ERR_NOT_SUPPORTED);

  // Read a message smaller than the FIDL header size.
  {
    uint8_t write_buffer[1] = {0};
    EXPECT_OK(
        server.write(/*flags=*/0, &write_buffer, sizeof(write_buffer), /*handles=*/nullptr, 0));
    EXPECT_EQ(message.Read(client.get(), /*flags=*/0), ZX_ERR_INVALID_ARGS);
  }

  // Read a message larger than our receive buffer.
  {
    uint8_t write_buffer[kBufferSize + 1];
    memset(write_buffer, 0xff, sizeof(write_buffer));
    EXPECT_OK(
        server.write(/*flags=*/0, &write_buffer, sizeof(write_buffer), /*handles=*/nullptr, 0));
    EXPECT_EQ(message.Read(client.get(), /*flags=*/ZX_CHANNEL_READ_MAY_DISCARD),
              ZX_ERR_BUFFER_TOO_SMALL);
  }

  // Read from closed channel.
  server.reset();
  EXPECT_EQ(message.Read(client.get(), /*flags=*/0), ZX_ERR_PEER_CLOSED);
}

TEST(MessagePart, IsStlContainerTest) {
  EXPECT_EQ(sizeof(uint8_t), sizeof(fidl::BytePart::value_type));
  EXPECT_EQ(sizeof(zx_handle_t), sizeof(fidl::HandlePart::value_type));

  EXPECT_EQ(sizeof(const uint8_t*), sizeof(fidl::BytePart::const_iterator));
  EXPECT_EQ(sizeof(const zx_handle_t*), sizeof(fidl::HandlePart::const_iterator));
}

TEST(MessagePart, Size) {
  fidl::HLCPPOutgoingMessage message;

  EXPECT_EQ(message.bytes().size(), 0u);

  uint8_t dummy_msg[42];
  fidl::MessagePart msg(dummy_msg, 42, 10);

  EXPECT_EQ(msg.size(), 10u);

  fidl::MessagePart new_msg = std::move(msg);

  EXPECT_EQ(new_msg.size(), 10u);
  EXPECT_EQ(msg.size(), 0u);
}

TEST(MessagePart, WrapArray) {
  uint8_t dummy[42];

  auto full = fidl::MessagePart<uint8_t>::WrapFull(dummy);
  EXPECT_EQ(full.data(), dummy);
  EXPECT_EQ(full.actual(), 42);
  EXPECT_EQ(full.capacity(), 42);

  auto empty = fidl::MessagePart<uint8_t>::WrapEmpty(dummy);
  EXPECT_EQ(empty.data(), dummy);
  EXPECT_EQ(empty.actual(), 0);
  EXPECT_EQ(empty.capacity(), 42);
}

}  // namespace
