// Copyright 2019 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/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async-loop/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/fidl-async/cpp/bind.h>
#include <lib/fidl-utils/bind.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/txn_header.h>
#include <lib/zx/channel.h>
#include <lib/zx/eventpair.h>
#include <lib/zx/time.h>
#include <zircon/fidl.h>
#include <zircon/syscalls.h>

#include <atomic>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <utility>

#include <fidl/test/llcpp/dirent/c/fidl.h>
#include <zxtest/zxtest.h>

// Interface under test.
#include <fidl/test/llcpp/dirent/llcpp/fidl.h>

// Namespace shorthand for bindings generated code
namespace gen = ::llcpp::fidl::test::llcpp::dirent;

// Toy test data
namespace {

static_assert(gen::SMALL_DIR_VECTOR_SIZE == 3);

gen::DirEnt golden_dirents_array[gen::SMALL_DIR_VECTOR_SIZE] = {
    gen::DirEnt{
        .is_dir = false,
        .name = fidl::StringView{"ab"},
        .some_flags = 0,
    },
    gen::DirEnt{
        .is_dir = true,
        .name = fidl::StringView{"cde"},
        .some_flags = 1,
    },
    gen::DirEnt{
        .is_dir = false,
        .name = fidl::StringView{"fghi"},
        .some_flags = 2,
    },
};

auto golden_dirents() { return fidl::VectorView{fidl::unowned_ptr(golden_dirents_array), 3}; }

}  // namespace

// Manual server implementation, since the C binding does not support
// types with more than one level of indirection.
// The server is an async loop that reads messages from the channel.
// It uses the llcpp raw API to decode the message, then calls one of the handlers.
namespace manual_server {

class Server {
 public:
  Server(zx::channel chan)
      : chan_(std::move(chan)), loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {}

  zx_status_t Start() {
    zx_status_t status = loop_.StartThread("llcpp_manual_server");
    if (status != ZX_OK) {
      return status;
    }
    return fidl_bind(loop_.dispatcher(), chan_.get(), Server::FidlDispatch, this, nullptr);
  }

  uint64_t CountNumDirectoriesNumCalls() const { return count_num_directories_num_calls_.load(); }

  uint64_t ReadDirNumCalls() const { return read_dir_num_calls_.load(); }

  uint64_t ConsumeDirectoriesNumCalls() const { return consume_directories_num_calls_.load(); }

  uint64_t OneWayDirentsNumCalls() const { return one_way_dirents_num_calls_.load(); }

 private:
  template <typename FidlType>
  zx_status_t Reply(fidl_txn_t* txn, FidlType* value) {
    fidl::OwnedEncodedMessage<FidlType> encoded(value);
    zx_status_t status = txn->reply(txn, encoded.GetOutgoingMessage().message());
    encoded.GetOutgoingMessage().ReleaseHandles();
    return status;
  }

  zx_status_t DoCountNumDirectories(
      fidl_txn_t* txn,
      fidl::DecodedMessage<gen::DirEntTestInterface::CountNumDirectoriesRequest>& decoded) {
    count_num_directories_num_calls_.fetch_add(1);
    const auto& request = *decoded.PrimaryObject();
    int64_t count = 0;
    for (const auto& dirent : request.dirents) {
      if (dirent.is_dir) {
        count++;
      }
    }
    gen::DirEntTestInterface::CountNumDirectoriesResponse response(count);
    response._hdr.txid = request._hdr.txid;
    return Reply(txn, &response);
  }

  zx_status_t DoReadDir(fidl_txn_t* txn,
                        fidl::DecodedMessage<gen::DirEntTestInterface::ReadDirRequest>& decoded) {
    read_dir_num_calls_.fetch_add(1);
    auto golden = golden_dirents();
    gen::DirEntTestInterface::ReadDirResponse response(golden);
    response._hdr.txid = decoded.PrimaryObject()->_hdr.txid;
    return Reply(txn, &response);
  }

  zx_status_t DoConsumeDirectories(
      fidl_txn_t* txn,
      fidl::DecodedMessage<gen::DirEntTestInterface::ConsumeDirectoriesRequest>& decoded) {
    consume_directories_num_calls_.fetch_add(1);
    EXPECT_EQ(decoded.PrimaryObject()->dirents.count(), 3);
    gen::DirEntTestInterface::ConsumeDirectoriesResponse response;
    fidl_init_txn_header(&response._hdr, 0, decoded.PrimaryObject()->_hdr.ordinal);
    return Reply(txn, &response);
  }

  zx_status_t DoOneWayDirents(
      fidl_txn_t* txn,
      fidl::DecodedMessage<gen::DirEntTestInterface::OneWayDirentsRequest>& decoded) {
    one_way_dirents_num_calls_.fetch_add(1);
    EXPECT_EQ(decoded.PrimaryObject()->dirents.count(), 3);
    EXPECT_OK(decoded.PrimaryObject()->ep.signal_peer(0, ZX_EVENTPAIR_SIGNALED));
    // No response required for one-way calls.
    return ZX_OK;
  }

  template <typename FidlType>
  static fidl::DecodedMessage<FidlType> DecodeAs(fidl_incoming_msg_t* msg) {
    return fidl::DecodedMessage<FidlType>(msg);
  }

  static zx_status_t FidlDispatch(void* ctx, fidl_txn_t* txn, fidl_incoming_msg_t* msg,
                                  const void* ops) {
    if (msg->num_bytes < sizeof(fidl_message_header_t)) {
      FidlHandleInfoCloseMany(msg->handles, msg->num_handles);
      return ZX_ERR_INVALID_ARGS;
    }
    fidl_message_header_t* hdr = reinterpret_cast<fidl_message_header_t*>(msg->bytes);
    Server* server = reinterpret_cast<Server*>(ctx);
    switch (hdr->ordinal) {
      case fidl_test_llcpp_dirent_DirEntTestInterfaceCountNumDirectoriesOrdinal: {
        auto result = DecodeAs<gen::DirEntTestInterface::CountNumDirectoriesRequest>(msg);
        if (!result.ok()) {
          return result.status();
        }
        return server->DoCountNumDirectories(txn, result);
      }
      case fidl_test_llcpp_dirent_DirEntTestInterfaceReadDirOrdinal: {
        auto result = DecodeAs<gen::DirEntTestInterface::ReadDirRequest>(msg);
        if (!result.ok()) {
          return result.status();
        }
        return server->DoReadDir(txn, result);
      }
      case fidl_test_llcpp_dirent_DirEntTestInterfaceConsumeDirectoriesOrdinal: {
        auto result = DecodeAs<gen::DirEntTestInterface::ConsumeDirectoriesRequest>(msg);
        if (!result.ok()) {
          return result.status();
        }
        return server->DoConsumeDirectories(txn, result);
      }
      case fidl_test_llcpp_dirent_DirEntTestInterfaceOneWayDirentsOrdinal: {
        auto result = DecodeAs<gen::DirEntTestInterface::OneWayDirentsRequest>(msg);
        if (!result.ok()) {
          return result.status();
        }
        return server->DoOneWayDirents(txn, result);
      }
      default:
        return ZX_ERR_NOT_SUPPORTED;
    }
  }

  zx::channel chan_;
  async::Loop loop_;

  std::atomic<uint64_t> count_num_directories_num_calls_ = 0;
  std::atomic<uint64_t> read_dir_num_calls_ = 0;
  std::atomic<uint64_t> consume_directories_num_calls_ = 0;
  std::atomic<uint64_t> one_way_dirents_num_calls_ = 0;
};

}  // namespace manual_server

// Server implemented with low-level C++ FIDL bindings
namespace llcpp_server {

class ServerBase : public gen::DirEntTestInterface::Interface {
 public:
  ServerBase(zx::channel chan)
      : chan_(std::move(chan)), loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {}

  zx_status_t Start() {
    zx_status_t status = loop_.StartThread("llcpp_bindings_server");
    if (status != ZX_OK) {
      return status;
    }
    return fidl::BindSingleInFlightOnly(loop_.dispatcher(), std::move(chan_), this);
  }

  uint64_t CountNumDirectoriesNumCalls() const { return count_num_directories_num_calls_.load(); }

  uint64_t ReadDirNumCalls() const { return read_dir_num_calls_.load(); }

  uint64_t ConsumeDirectoriesNumCalls() const { return consume_directories_num_calls_.load(); }

  uint64_t OneWayDirentsNumCalls() const { return one_way_dirents_num_calls_.load(); }

 protected:
  async_dispatcher_t* dispatcher() const { return loop_.dispatcher(); }

  std::atomic<uint64_t> count_num_directories_num_calls_ = 0;
  std::atomic<uint64_t> read_dir_num_calls_ = 0;
  std::atomic<uint64_t> consume_directories_num_calls_ = 0;
  std::atomic<uint64_t> one_way_dirents_num_calls_ = 0;

 private:
  zx::channel chan_;
  async::Loop loop_;
};

// There are three implementations each exercising a different flavor of the reply API:
// C-style, caller-allocating, in-place, and async.

class CFlavorServer : public ServerBase {
 public:
  CFlavorServer(zx::channel chan) : ServerBase(std::move(chan)) {}

  void CountNumDirectories(fidl::VectorView<gen::DirEnt> dirents,
                           CountNumDirectoriesCompleter::Sync& txn) override {
    count_num_directories_num_calls_.fetch_add(1);
    int64_t count = 0;
    for (const auto& dirent : dirents) {
      if (dirent.is_dir) {
        count++;
      }
    }
    txn.Reply(count);
  }

  void ReadDir(ReadDirCompleter::Sync& txn) override {
    read_dir_num_calls_.fetch_add(1);
    txn.Reply(golden_dirents());
  }

  // |ConsumeDirectories| has zero number of arguments in its return value, hence only the
  // C-flavor reply API is generated.
  void ConsumeDirectories(fidl::VectorView<gen::DirEnt> dirents,
                          ConsumeDirectoriesCompleter::Sync& txn) override {
    consume_directories_num_calls_.fetch_add(1);
    EXPECT_EQ(dirents.count(), 3);
    txn.Reply();
  }

  // |OneWayDirents| has no return value, hence there is no reply API generated
  void OneWayDirents(fidl::VectorView<gen::DirEnt> dirents, zx::eventpair ep,
                     OneWayDirentsCompleter::Sync& txn) override {
    one_way_dirents_num_calls_.fetch_add(1);
    EXPECT_EQ(dirents.count(), 3);
    EXPECT_OK(ep.signal_peer(0, ZX_EVENTPAIR_SIGNALED));
    // No response required for one-way calls.
  }
};

class CallerAllocateServer : public ServerBase {
 public:
  CallerAllocateServer(zx::channel chan) : ServerBase(std::move(chan)) {}

  void CountNumDirectories(fidl::VectorView<gen::DirEnt> dirents,
                           CountNumDirectoriesCompleter::Sync& txn) override {
    count_num_directories_num_calls_.fetch_add(1);
    int64_t count = 0;
    for (const auto& dirent : dirents) {
      if (dirent.is_dir) {
        count++;
      }
    }
    fidl::Buffer<gen::DirEntTestInterface::CountNumDirectoriesResponse> buffer;
    txn.Reply(buffer.view(), count);
  }

  void ReadDir(ReadDirCompleter::Sync& txn) override {
    read_dir_num_calls_.fetch_add(1);
    fidl::Buffer<gen::DirEntTestInterface::ReadDirResponse> buffer;
    txn.Reply(buffer.view(), golden_dirents());
  }

  // |ConsumeDirectories| has zero number of arguments in its return value, hence only the
  // C-flavor reply API is applicable.
  void ConsumeDirectories(fidl::VectorView<gen::DirEnt> dirents,
                          ConsumeDirectoriesCompleter::Sync& txn) override {
    ZX_ASSERT_MSG(false, "Never used by unit tests");
  }

  // |OneWayDirents| has no return value, hence there is no reply API generated
  void OneWayDirents(fidl::VectorView<gen::DirEnt> dirents, zx::eventpair ep,
                     OneWayDirentsCompleter::Sync&) override {
    ZX_ASSERT_MSG(false, "Never used by unit tests");
  }
};

// Every reply is delayed using async::PostTask
class AsyncReplyServer : public ServerBase {
 public:
  AsyncReplyServer(zx::channel chan) : ServerBase(std::move(chan)) {}

  void CountNumDirectories(fidl::VectorView<gen::DirEnt> dirents,
                           CountNumDirectoriesCompleter::Sync& txn) override {
    count_num_directories_num_calls_.fetch_add(1);
    int64_t count = 0;
    for (const auto& dirent : dirents) {
      if (dirent.is_dir) {
        count++;
      }
    }
    async::PostTask(dispatcher(), [txn = txn.ToAsync(), count]() mutable { txn.Reply(count); });
  }

  void ReadDir(ReadDirCompleter::Sync& txn) override {
    read_dir_num_calls_.fetch_add(1);
    async::PostTask(dispatcher(), [txn = txn.ToAsync()]() mutable { txn.Reply(golden_dirents()); });
  }

  void ConsumeDirectories(fidl::VectorView<gen::DirEnt> dirents,
                          ConsumeDirectoriesCompleter::Sync& txn) override {
    consume_directories_num_calls_.fetch_add(1);
    EXPECT_EQ(dirents.count(), 3);
    async::PostTask(dispatcher(), [txn = txn.ToAsync()]() mutable { txn.Reply(); });
  }

  // |OneWayDirents| has no return value, hence there is no reply API generated
  void OneWayDirents(fidl::VectorView<gen::DirEnt> dirents, zx::eventpair ep,
                     OneWayDirentsCompleter::Sync&) override {
    ZX_ASSERT_MSG(false, "Never used by unit tests");
  }
};

}  // namespace llcpp_server

// Parametric tests allowing choosing a custom server implementation
namespace {

class Random {
 public:
  Random(
      unsigned int seed = static_cast<unsigned int>(zxtest::Runner::GetInstance()->random_seed()))
      : seed_(seed) {}

  unsigned int seed() const { return seed_; }

  unsigned int UpTo(unsigned int limit) {
    unsigned int next = rand_r(&seed_);
    return next % limit;
  }

 private:
  unsigned int seed_;
};

template <size_t kNumDirents>
fidl::Array<gen::DirEnt, kNumDirents> RandomlyFillDirEnt(char* name) {
  Random random;
  fidl::Array<gen::DirEnt, kNumDirents> dirents;
  for (size_t i = 0; i < kNumDirents; i++) {
    int str_len = random.UpTo(gen::TEST_MAX_PATH) + 1;
    bool is_dir = random.UpTo(2) == 0;
    int32_t flags = static_cast<int32_t>(random.UpTo(1000));
    dirents[i] = gen::DirEnt{.is_dir = is_dir,
                             .name = fidl::unowned_str(name, static_cast<uint64_t>(str_len)),
                             .some_flags = flags};
  }
  return dirents;
}

template <typename Server>
void SimpleCountNumDirectories() {
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));
  Server server(std::move(server_chan));
  ASSERT_OK(server.Start());
  gen::DirEntTestInterface::SyncClient client(std::move(client_chan));

  constexpr size_t kNumDirents = 80;
  std::unique_ptr<char[]> name(new char[gen::TEST_MAX_PATH]);
  for (uint32_t i = 0; i < gen::TEST_MAX_PATH; i++) {
    name[i] = 'A';
  }
  ASSERT_EQ(server.CountNumDirectoriesNumCalls(), 0);
  constexpr uint64_t kNumIterations = 100;
  // Stress test linearizing dirents
  for (uint64_t iter = 0; iter < kNumIterations; iter++) {
    auto dirents = RandomlyFillDirEnt<kNumDirents>(name.get());
    auto result = client.CountNumDirectories(fidl::unowned_vec(dirents));
    int64_t expected_num_dir = 0;
    for (const auto& dirent : dirents) {
      if (dirent.is_dir) {
        expected_num_dir++;
      }
    }
    ASSERT_OK(result.status());
    ASSERT_EQ(expected_num_dir, result.Unwrap()->num_dir);
  }
  ASSERT_EQ(server.CountNumDirectoriesNumCalls(), kNumIterations);
}

template <typename Server>
void CallerAllocateCountNumDirectories() {
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));
  Server server(std::move(server_chan));
  ASSERT_OK(server.Start());
  gen::DirEntTestInterface::SyncClient client(std::move(client_chan));

  Random random;
  constexpr size_t kNumDirents = 80;
  std::unique_ptr<char[]> name(new char[gen::TEST_MAX_PATH]);
  for (uint32_t i = 0; i < gen::TEST_MAX_PATH; i++) {
    name[i] = 'B';
  }
  ASSERT_EQ(server.CountNumDirectoriesNumCalls(), 0);
  constexpr uint64_t kNumIterations = 100;
  // Stress test linearizing dirents
  for (uint64_t iter = 0; iter < kNumIterations; iter++) {
    auto dirents = RandomlyFillDirEnt<kNumDirents>(name.get());
    fidl::Buffer<gen::DirEntTestInterface::CountNumDirectoriesRequest> request_buffer;
    fidl::Buffer<gen::DirEntTestInterface::CountNumDirectoriesResponse> response_buffer;
    auto result = client.CountNumDirectories(request_buffer.view(), fidl::unowned_vec(dirents),
                                             response_buffer.view());
    int64_t expected_num_dir = 0;
    for (const auto& dirent : dirents) {
      if (dirent.is_dir) {
        expected_num_dir++;
      }
    }
    ASSERT_OK(result.status());
    ASSERT_NULL(result.error());
    ASSERT_EQ(expected_num_dir, result.Unwrap()->num_dir);
  }
  ASSERT_EQ(server.CountNumDirectoriesNumCalls(), kNumIterations);
}

template <typename Server>
void CallerAllocateReadDir() {
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));
  Server server(std::move(server_chan));
  ASSERT_OK(server.Start());
  gen::DirEntTestInterface::SyncClient client(std::move(client_chan));

  ASSERT_EQ(server.ReadDirNumCalls(), 0);
  constexpr uint64_t kNumIterations = 100;
  // Stress test server-linearizing dirents
  for (uint64_t iter = 0; iter < kNumIterations; iter++) {
    fidl::Buffer<gen::DirEntTestInterface::ReadDirResponse> buffer;
    auto result = client.ReadDir(buffer.view());
    ASSERT_OK(result.status());
    ASSERT_NULL(result.error(), "%s", result.error());
    const auto& dirents = result.Unwrap()->dirents;
    ASSERT_EQ(dirents.count(), golden_dirents().count());
    for (uint64_t i = 0; i < dirents.count(); i++) {
      auto& actual = dirents[i];
      auto& expected = golden_dirents()[i];
      EXPECT_EQ(actual.is_dir, expected.is_dir);
      EXPECT_EQ(actual.some_flags, expected.some_flags);
      ASSERT_EQ(actual.name.size(), expected.name.size());
      EXPECT_BYTES_EQ(reinterpret_cast<const uint8_t*>(actual.name.data()),
                      reinterpret_cast<const uint8_t*>(expected.name.data()), actual.name.size(),
                      "dirent name mismatch");
    }
  }
  ASSERT_EQ(server.ReadDirNumCalls(), kNumIterations);
}

template <typename Server>
void SimpleConsumeDirectories() {
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));
  Server server(std::move(server_chan));
  ASSERT_OK(server.Start());
  gen::DirEntTestInterface::SyncClient client(std::move(client_chan));

  ASSERT_EQ(server.ConsumeDirectoriesNumCalls(), 0);
  ASSERT_OK(client.ConsumeDirectories(golden_dirents()).status());
  ASSERT_EQ(server.ConsumeDirectoriesNumCalls(), 1);
}

template <typename Server>
void CallerAllocateConsumeDirectories() {
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));
  Server server(std::move(server_chan));
  ASSERT_OK(server.Start());
  gen::DirEntTestInterface::SyncClient client(std::move(client_chan));

  ASSERT_EQ(server.ConsumeDirectoriesNumCalls(), 0);
  fidl::Buffer<gen::DirEntTestInterface::ConsumeDirectoriesRequest> request_buffer;
  fidl::Buffer<gen::DirEntTestInterface::ConsumeDirectoriesResponse> response_buffer;
  auto result =
      client.ConsumeDirectories(request_buffer.view(), golden_dirents(), response_buffer.view());
  ASSERT_OK(result.status());
  ASSERT_NULL(result.error(), "%s", result.error());
  ASSERT_EQ(server.ConsumeDirectoriesNumCalls(), 1);
}

template <typename Server>
void SimpleOneWayDirents() {
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));
  Server server(std::move(server_chan));
  ASSERT_OK(server.Start());
  gen::DirEntTestInterface::SyncClient client(std::move(client_chan));

  zx::eventpair client_ep, server_ep;
  ASSERT_OK(zx::eventpair::create(0, &client_ep, &server_ep));
  ASSERT_EQ(server.OneWayDirentsNumCalls(), 0);
  ASSERT_OK(client.OneWayDirents(golden_dirents(), std::move(server_ep)).status());
  zx_signals_t signals = 0;
  client_ep.wait_one(ZX_EVENTPAIR_SIGNALED, zx::time::infinite(), &signals);
  ASSERT_EQ(signals & ZX_EVENTPAIR_SIGNALED, ZX_EVENTPAIR_SIGNALED);
  ASSERT_EQ(server.OneWayDirentsNumCalls(), 1);
}

template <typename Server>
void CallerAllocateOneWayDirents() {
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));
  Server server(std::move(server_chan));
  ASSERT_OK(server.Start());
  gen::DirEntTestInterface::SyncClient client(std::move(client_chan));

  zx::eventpair client_ep, server_ep;
  ASSERT_OK(zx::eventpair::create(0, &client_ep, &server_ep));
  ASSERT_EQ(server.OneWayDirentsNumCalls(), 0);
  fidl::Buffer<gen::DirEntTestInterface::OneWayDirentsRequest> buffer;
  ASSERT_OK(client.OneWayDirents(buffer.view(), golden_dirents(), std::move(server_ep)).status());
  zx_signals_t signals = 0;
  client_ep.wait_one(ZX_EVENTPAIR_SIGNALED, zx::time::infinite(), &signals);
  ASSERT_EQ(signals & ZX_EVENTPAIR_SIGNALED, ZX_EVENTPAIR_SIGNALED);
  ASSERT_EQ(server.OneWayDirentsNumCalls(), 1);
}

template <typename DirentArray>
void AssertReadOnDirentsEvent(zx::channel chan, const DirentArray& expected_dirents) {
  class EventHandler : public gen::DirEntTestInterface::EventHandler {
   public:
    explicit EventHandler(const DirentArray& expected_dirents)
        : expected_dirents_(expected_dirents) {}

    zx_status_t status() const { return status_; }

    void OnDirents(gen::DirEntTestInterface::OnDirentsResponse* event) override {
      EXPECT_EQ(event->dirents.count(), expected_dirents_.size());
      if (event->dirents.count() != expected_dirents_.size()) {
        status_ = ZX_ERR_INVALID_ARGS;
      } else {
        for (uint64_t i = 0; i < event->dirents.count(); i++) {
          EXPECT_EQ(event->dirents[i].is_dir, expected_dirents_[i].is_dir);
          EXPECT_EQ(event->dirents[i].some_flags, expected_dirents_[i].some_flags);
          EXPECT_EQ(event->dirents[i].name.size(), expected_dirents_[i].name.size());
          EXPECT_BYTES_EQ(reinterpret_cast<const uint8_t*>(event->dirents[i].name.data()),
                          reinterpret_cast<const uint8_t*>(expected_dirents_[i].name.data()),
                          event->dirents[i].name.size(), "dirent name mismatch");
        }
      }
    }

    zx_status_t Unknown() override {
      ADD_FAILURE("unknown event received; expected OnDirents");
      return ZX_ERR_INVALID_ARGS;
    }

   private:
    const DirentArray& expected_dirents_;
    zx_status_t status_ = ZX_OK;
  };

  EventHandler event_handler(expected_dirents);
  ::fidl::Result result = event_handler.HandleOneEvent(zx::unowned_channel(chan));
  ASSERT_OK(result.status());
  ASSERT_OK(event_handler.status());
}

}  // namespace

TEST(DirentServerTest, CFlavorSendOnDirents) {
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));

  constexpr size_t kNumDirents = 80;
  std::unique_ptr<char[]> name(new char[gen::TEST_MAX_PATH]);
  for (uint32_t i = 0; i < gen::TEST_MAX_PATH; i++) {
    name[i] = 'A';
  }
  auto dirents = RandomlyFillDirEnt<kNumDirents>(name.get());
  gen::DirEntTestInterface::EventSender event_sender(std::move(server_chan));
  auto status = event_sender.OnDirents(fidl::unowned_vec(dirents));
  ASSERT_OK(status);
  ASSERT_NO_FATAL_FAILURES(AssertReadOnDirentsEvent(std::move(client_chan), dirents));
}

TEST(DirentServerTest, CallerAllocateSendOnDirents) {
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));

  constexpr size_t kNumDirents = 80;
  std::unique_ptr<char[]> name(new char[gen::TEST_MAX_PATH]);
  for (uint32_t i = 0; i < gen::TEST_MAX_PATH; i++) {
    name[i] = 'B';
  }
  auto dirents = RandomlyFillDirEnt<kNumDirents>(name.get());
  auto buffer = std::make_unique<fidl::Buffer<gen::DirEntTestInterface::OnDirentsResponse>>();
  gen::DirEntTestInterface::EventSender event_sender(std::move(server_chan));
  auto status = event_sender.OnDirents(buffer->view(), fidl::unowned_vec(dirents));
  ASSERT_OK(status);
  ASSERT_NO_FATAL_FAILURES(AssertReadOnDirentsEvent(std::move(client_chan), dirents));
}

// Parameterized tests
TEST(DirentClientTest, SimpleCountNumDirectories) {
  SimpleCountNumDirectories<manual_server::Server>();
}

TEST(DirentClientTest, CallerAllocateCountNumDirectories) {
  CallerAllocateCountNumDirectories<manual_server::Server>();
}

TEST(DirentClientTest, CallerAllocateReadDir) { CallerAllocateReadDir<manual_server::Server>(); }

TEST(DirentClientTest, SimpleConsumeDirectories) {
  SimpleConsumeDirectories<manual_server::Server>();
}

TEST(DirentClientTest, CallerAllocateConsumeDirectories) {
  CallerAllocateConsumeDirectories<manual_server::Server>();
}

TEST(DirentClientTest, SimpleOneWayDirents) { SimpleOneWayDirents<manual_server::Server>(); }

TEST(DirentClientTest, CallerAllocateOneWayDirents) {
  CallerAllocateOneWayDirents<manual_server::Server>();
}

TEST(DirentServerTest, SimpleCountNumDirectoriesWithCFlavorServer) {
  SimpleCountNumDirectories<llcpp_server::CFlavorServer>();
}

TEST(DirentServerTest, SimpleCountNumDirectoriesWithCallerAllocateServer) {
  SimpleCountNumDirectories<llcpp_server::CallerAllocateServer>();
}

TEST(DirentServerTest, SimpleCountNumDirectoriesWithAsyncReplyServer) {
  SimpleCountNumDirectories<llcpp_server::AsyncReplyServer>();
}

TEST(DirentServerTest, SimpleConsumeDirectoriesWithCFlavorServer) {
  SimpleConsumeDirectories<llcpp_server::CFlavorServer>();
}

TEST(DirentServerTest, SimpleConsumeDirectoriesWithAsyncReplyServer) {
  SimpleConsumeDirectories<llcpp_server::AsyncReplyServer>();
}

TEST(DirentServerTest, SimpleOneWayDirentsWithCFlavorServer) {
  SimpleOneWayDirents<llcpp_server::CFlavorServer>();
}
