// 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/internal/message_reader.h"

#include <lib/zx/channel.h>
#include <zircon/errors.h>
#include <zircon/fidl.h>

#include <fidl/test/misc/cpp/fidl.h>
#include <zxtest/zxtest.h>

#include "lib/fidl/cpp/binding.h"
#include "lib/fidl/cpp/test/async_loop_for_test.h"
#include "lib/fidl/txn_header.h"

namespace fidl {
namespace internal {
namespace {

class CopyingMessageHandler : public MessageHandler {
 public:
  int message_count_ = 0;
  int channel_gone_count_ = 0;
  std::vector<uint8_t> bytes_;
  std::vector<zx_handle_info_t> handles_;

  zx_status_t OnMessage(HLCPPIncomingMessage message) override {
    ++message_count_;
    auto& bytes = message.bytes();
    bytes_ = std::vector<uint8_t>(bytes.data(), bytes.data() + bytes.actual());
    auto& handles = message.handles();
    handles_ = std::vector<zx_handle_info_t>(handles.data(), handles.data() + handles.actual());
    return ZX_OK;
  }

  void OnChannelGone() override { ++channel_gone_count_; }
};

class StatusMessageHandler : public MessageHandler {
 public:
  zx_status_t status = ZX_OK;

  zx_status_t OnMessage(HLCPPIncomingMessage message) override { return status; }
};

class CallbackMessageHandler : public MessageHandler {
 public:
  fit::function<zx_status_t(HLCPPIncomingMessage)> callback;

  zx_status_t OnMessage(HLCPPIncomingMessage message) override {
    return callback(std::move(message));
  }
};

class DestructionCounter {
 public:
  DestructionCounter(int* counter) : counter_(counter) {}

  DestructionCounter(DestructionCounter&& other) : counter_(other.counter_) {
    other.counter_ = nullptr;
  }

  DestructionCounter(const DestructionCounter&) = delete;
  DestructionCounter& operator=(const DestructionCounter&) = delete;
  DestructionCounter& operator=(DestructionCounter&& other) = delete;

  ~DestructionCounter() {
    if (counter_)
      ++(*counter_);
  }

 private:
  int* counter_ = nullptr;
};

class EchoServer : public fidl::test::misc::Echo {
 public:
  explicit EchoServer(fidl::InterfaceRequest<fidl::test::misc::Echo> request)
      : binding_(this, std::move(request)) {}

  void EchoString(fidl::StringPtr value, EchoStringCallback callback) override { callback(value); }

  void Close() { binding_.Close(10); }

 private:
  fidl::Binding<fidl::test::misc::Echo> binding_;
};

template <size_t N>
struct StringMessage {
  FIDL_ALIGNDECL
  fidl_message_header_t hdr;
  std::array<char, N> data;
};

constexpr size_t kMessageDataStart = 16;

template <size_t N>
StringMessage<N> CreateFidlMessage(const char (&data)[N]) {
  StringMessage<N> msg;
  fidl_init_txn_header(&msg.hdr, 0, 0);
  memcpy(&msg.data, data, N);
  return msg;
}

const auto test_msg0 = CreateFidlMessage("hello");
const uint32_t test_msg0_size = 21;
const auto test_msg1 = CreateFidlMessage(", world");
const uint32_t test_msg1_size = 23;
const auto test_msg2 = CreateFidlMessage("!");
const uint32_t test_msg2_size = 17;

TEST(MessageReader, Trivial) { MessageReader reader; }

TEST(MessageReader, Bind) {
  MessageReader reader;
  EXPECT_EQ(ZX_OK, reader.Bind(zx::channel()));
  EXPECT_FALSE(reader.is_bound());
  EXPECT_EQ(ZX_HANDLE_INVALID, reader.Unbind().get());
}

TEST(MessageReader, Control) {
  CopyingMessageHandler handler;
  MessageReader reader(&handler);

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

  fidl::test::AsyncLoopForTest loop;

  EXPECT_FALSE(reader.is_bound());
  zx_handle_t saved = h1.get();
  reader.Bind(std::move(h1));
  EXPECT_TRUE(reader.is_bound());
  EXPECT_EQ(saved, reader.channel().get());

  EXPECT_EQ(0, handler.channel_gone_count_);
  zx::channel h3 = reader.Unbind();
  EXPECT_EQ(saved, h3.get());
  EXPECT_EQ(1, handler.channel_gone_count_);
  reader.Bind(std::move(h3));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));
  EXPECT_EQ(0, handler.message_count_);

  EXPECT_EQ(ZX_OK, reader.WaitAndDispatchOneMessageUntil(zx::time::infinite()));
  EXPECT_EQ(1, handler.message_count_);
  EXPECT_EQ(test_msg0_size, handler.bytes_.size());
  EXPECT_EQ('h', handler.bytes_[kMessageDataStart]);
  EXPECT_EQ(0u, handler.handles_.size());

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg1, test_msg1_size, nullptr, 0));
  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(2, handler.message_count_);
  EXPECT_EQ(test_msg1_size, handler.bytes_.size());
  EXPECT_EQ(',', handler.bytes_[kMessageDataStart]);
  EXPECT_EQ(0u, handler.handles_.size());

  int error_count = 0;
  reader.set_error_handler([&error_count](zx_status_t status) {
    EXPECT_EQ(ZX_ERR_PEER_CLOSED, status);
    ++error_count;
  });
  EXPECT_TRUE(reader.has_error_handler());

  h2.reset();
  EXPECT_EQ(0, error_count);
  EXPECT_EQ(1, handler.channel_gone_count_);
  EXPECT_TRUE(reader.is_bound());

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(1, error_count);
  EXPECT_EQ(2, handler.channel_gone_count_);
  EXPECT_FALSE(reader.is_bound());
}

TEST(MessageReader, HandlerError) {
  StatusMessageHandler handler;
  handler.status = ZX_ERR_INTERNAL;

  MessageReader reader;
  reader.set_message_handler(&handler);

  int error_count = 0;
  reader.set_error_handler([&error_count](zx_status_t status) {
    EXPECT_EQ(ZX_ERR_INTERNAL, status);
    ++error_count;
  });

  fidl::test::AsyncLoopForTest loop;

  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  reader.Bind(std::move(h1));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));

  EXPECT_EQ(0, error_count);
  EXPECT_TRUE(reader.is_bound());

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(1, error_count);
  EXPECT_FALSE(reader.is_bound());
}

TEST(MessageReader, HandlerErrorWithoutErrorHandler) {
  StatusMessageHandler handler;
  handler.status = ZX_ERR_INTERNAL;

  MessageReader reader;
  reader.set_message_handler(&handler);

  EXPECT_FALSE(reader.has_error_handler());

  fidl::test::AsyncLoopForTest loop;

  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  reader.Bind(std::move(h1));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));

  EXPECT_TRUE(reader.is_bound());

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_FALSE(reader.is_bound());
}

TEST(MessageReader, BindTwice) {
  MessageReader reader;
  fidl::test::AsyncLoopForTest loop;

  zx::channel h1, h2, j1, j2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &j1, &j2));
  zx_handle_t saved = j1.get();
  reader.Bind(std::move(h1));
  reader.Bind(std::move(j1));

  zx_signals_t pending = ZX_SIGNAL_NONE;
  EXPECT_EQ(ZX_OK, h2.wait_one(ZX_CHANNEL_PEER_CLOSED, zx::time(), &pending));
  EXPECT_TRUE(pending & ZX_CHANNEL_PEER_CLOSED);

  EXPECT_EQ(saved, reader.channel().get());
}

TEST(MessageReader, WaitAndDispatchOneMessageUntilErrors) {
  MessageReader reader;
  int error_count = 0;
  reader.set_error_handler([&error_count](zx_status_t status) {
    EXPECT_EQ(ZX_ERR_PEER_CLOSED, status);
    ++error_count;
  });

  EXPECT_TRUE(reader.has_error_handler());
  EXPECT_EQ(0, error_count);
  EXPECT_EQ(ZX_ERR_BAD_STATE, reader.WaitAndDispatchOneMessageUntil(zx::time()));
  EXPECT_EQ(0, error_count);

  fidl::test::AsyncLoopForTest loop;

  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  h1.replace(ZX_RIGHT_NONE, &h1);
  EXPECT_EQ(ZX_ERR_ACCESS_DENIED, reader.Bind(std::move(h1)));
  EXPECT_EQ(0, error_count);
  EXPECT_FALSE(reader.is_bound());

  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  EXPECT_EQ(ZX_OK, reader.Bind(std::move(h1)));
  EXPECT_EQ(0, error_count);
  EXPECT_TRUE(reader.is_bound());
  EXPECT_EQ(ZX_ERR_TIMED_OUT, reader.WaitAndDispatchOneMessageUntil(zx::time()));
  EXPECT_EQ(0, error_count);
  EXPECT_TRUE(reader.is_bound());

  reader.Bind(std::move(h2));

  EXPECT_EQ(0, error_count);
  EXPECT_TRUE(reader.is_bound());
  EXPECT_EQ(ZX_ERR_PEER_CLOSED, reader.WaitAndDispatchOneMessageUntil(zx::time()));
  EXPECT_EQ(1, error_count);
  EXPECT_FALSE(reader.is_bound());
}

TEST(MessageReader, UnbindDuringHandler) {
  MessageReader reader;
  zx::channel stash;

  CallbackMessageHandler handler;
  handler.callback = [&reader, &stash](HLCPPIncomingMessage message) {
    stash = reader.Unbind();
    return ZX_OK;
  };

  reader.set_message_handler(&handler);

  int error_count = 0;
  reader.set_error_handler([&error_count](zx_status_t status) {
    EXPECT_EQ(ZX_ERR_INVALID_ARGS, status);
    ++error_count;
  });
  EXPECT_TRUE(reader.has_error_handler());

  fidl::test::AsyncLoopForTest loop;

  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  reader.Bind(std::move(h1));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));

  EXPECT_EQ(0, error_count);
  EXPECT_TRUE(reader.is_bound());
  EXPECT_FALSE(stash.is_valid());

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(0, error_count);
  EXPECT_FALSE(reader.is_bound());
  EXPECT_TRUE(stash.is_valid());

  // The handler unbound the channel, which means the reader is no longer
  // listening to the channel.

  CopyingMessageHandler logger;
  reader.set_message_handler(&logger);

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));
  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(0, error_count);
  EXPECT_FALSE(reader.is_bound());
  EXPECT_EQ(0, logger.message_count_);

  reader.set_message_handler(nullptr);
}

TEST(MessageReader, ShouldWaitFromRead) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  CallbackMessageHandler handler;
  MessageReader reader(&handler);

  int message_count = 0;
  handler.callback = [&message_count, &reader](HLCPPIncomingMessage message) {
    ++message_count;
    uint32_t actual_bytes, actual_handles;
    EXPECT_EQ(ZX_ERR_BUFFER_TOO_SMALL,
              reader.channel().read(ZX_CHANNEL_READ_MAY_DISCARD, nullptr, nullptr, 0, 0,
                                    &actual_bytes, &actual_handles));
    return ZX_OK;
  };

  int error_count = 0;
  reader.set_error_handler([&error_count](zx_status_t status) {
    EXPECT_EQ(ZX_ERR_CANCELED, status);
    ++error_count;
  });
  EXPECT_TRUE(reader.has_error_handler());

  fidl::test::AsyncLoopForTest loop;
  reader.Bind(std::move(h1));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));
  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg1, test_msg1_size, nullptr, 0));
  EXPECT_EQ(0, error_count);
  EXPECT_EQ(0, message_count);

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(0, error_count);
  EXPECT_EQ(1, message_count);
  EXPECT_TRUE(reader.is_bound());

  // The reader should still be listening to the channel.

  CopyingMessageHandler logger;
  reader.set_message_handler(&logger);

  auto msg = CreateFidlMessage("again!");
  EXPECT_EQ(ZX_OK, h2.write(0, &msg, 22, nullptr, 0));
  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(0, error_count);
  EXPECT_EQ(1, logger.message_count_);
  EXPECT_EQ(22u, logger.bytes_.size());
  EXPECT_EQ('a', logger.bytes_[kMessageDataStart]);

  reader.set_message_handler(nullptr);
}

TEST(MessageReader, ShouldWaitFromReadWithUnbind) {
  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));

  CallbackMessageHandler handler;
  MessageReader reader(&handler);

  int message_count = 0;
  handler.callback = [&message_count, &reader](HLCPPIncomingMessage message) {
    ++message_count;
    uint32_t actual_bytes, actual_handles;
    EXPECT_EQ(ZX_ERR_BUFFER_TOO_SMALL,
              reader.channel().read(ZX_CHANNEL_READ_MAY_DISCARD, nullptr, nullptr, 0, 0,
                                    &actual_bytes, &actual_handles));
    reader.Unbind();
    return ZX_OK;
  };

  int error_count = 0;
  reader.set_error_handler([&error_count](zx_status_t status) {
    EXPECT_EQ(ZX_ERR_INVALID_ARGS, status);
    ++error_count;
  });
  EXPECT_TRUE(reader.has_error_handler());

  fidl::test::AsyncLoopForTest loop;
  reader.Bind(std::move(h1));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));
  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg1, test_msg1_size, nullptr, 0));
  EXPECT_EQ(0, error_count);
  EXPECT_EQ(0, message_count);

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(0, error_count);
  EXPECT_EQ(1, message_count);
  EXPECT_FALSE(reader.is_bound());

  // The handler unbound the channel, so the reader should not be listening to
  // the channel anymore.

  EXPECT_EQ(ZX_ERR_PEER_CLOSED, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));

  reader.set_message_handler(nullptr);
}

TEST(MessageReader, NoHandler) {
  MessageReader reader;

  int error_count = 0;
  reader.set_error_handler([&error_count](zx_status_t status) {
    EXPECT_EQ(ZX_ERR_CANCELED, status);
    ++error_count;
  });
  EXPECT_TRUE(reader.has_error_handler());

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

  fidl::test::AsyncLoopForTest loop;
  reader.Bind(std::move(h1));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));
  EXPECT_EQ(0, error_count);

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(0, error_count);
  EXPECT_TRUE(reader.is_bound());
}

TEST(MessageReader, Reset) {
  MessageReader reader;

  int destruction_count = 0;
  DestructionCounter counter(&destruction_count);
  reader.set_error_handler([counter = std::move(counter)](zx_status_t status) {});
  EXPECT_TRUE(reader.has_error_handler());

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

  fidl::test::AsyncLoopForTest loop;
  reader.Bind(std::move(h1));

  EXPECT_TRUE(reader.is_bound());
  EXPECT_EQ(0, destruction_count);

  reader.Reset();

  EXPECT_FALSE(reader.is_bound());
  EXPECT_EQ(1, destruction_count);
}

TEST(MessageReader, TakeChannelAndErrorHandlerFrom) {
  StatusMessageHandler handler1;
  handler1.status = ZX_OK;

  MessageReader reader1;
  reader1.set_message_handler(&handler1);

  int error_count = 0;
  reader1.set_error_handler([&error_count](zx_status_t status) {
    EXPECT_EQ(ZX_ERR_INTERNAL, status);
    ++error_count;
  });
  EXPECT_TRUE(reader1.has_error_handler());

  StatusMessageHandler handler2;
  handler2.status = ZX_ERR_INTERNAL;

  MessageReader reader2;
  reader2.set_message_handler(&handler2);

  fidl::test::AsyncLoopForTest loop;

  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  reader1.Bind(std::move(h1));
  EXPECT_EQ(ZX_OK, reader2.TakeChannelAndErrorHandlerFrom(&reader1));
  EXPECT_FALSE(reader1.is_bound());
  EXPECT_TRUE(reader2.is_bound());

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));

  EXPECT_EQ(0, error_count);
  EXPECT_FALSE(reader1.is_bound());
  EXPECT_TRUE(reader2.is_bound());

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_EQ(1, error_count);
  EXPECT_FALSE(reader1.is_bound());
  EXPECT_FALSE(reader2.is_bound());
}

TEST(MessageReader, ReentrantDestruction) {
  std::unique_ptr<MessageReader> reader = std::make_unique<MessageReader>();

  int read_count = 0;

  CallbackMessageHandler handler;
  handler.callback = [&reader, &read_count](HLCPPIncomingMessage message) {
    ++read_count;
    reader.reset();
    return ZX_OK;
  };

  reader->set_message_handler(&handler);

  fidl::test::AsyncLoopForTest loop;

  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  reader->Bind(std::move(h1));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));
  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg1, test_msg1_size, nullptr, 0));

  EXPECT_TRUE(reader->is_bound());

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_FALSE(reader);

  // The handler destroyed the reader, which means the reader should have read
  // only one of the messages and its endpoint should be closed.

  EXPECT_EQ(1, read_count);
  EXPECT_EQ(ZX_ERR_PEER_CLOSED, h2.write(0, "!", 1, nullptr, 0));
}

TEST(MessageReader, DoubleReentrantDestruction) {
  std::unique_ptr<MessageReader> reader = std::make_unique<MessageReader>();

  int read_count = 0;

  CallbackMessageHandler handler;
  handler.callback = [&reader, &read_count](HLCPPIncomingMessage message) {
    ++read_count;
    if (read_count == 1) {
      reader->WaitAndDispatchOneMessageUntil(zx::time::infinite());
    } else {
      reader.reset();
    }
    return ZX_OK;
  };

  reader->set_message_handler(&handler);

  fidl::test::AsyncLoopForTest loop;

  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  reader->Bind(std::move(h1));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));
  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg1, test_msg1_size, nullptr, 0));
  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg2, test_msg2_size, nullptr, 0));

  EXPECT_TRUE(reader->is_bound());

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_FALSE(reader);

  // The handler destroyed the reader in a nested callstack, which means the
  // reader should have read two of the messages and its endpoint should be
  // closed.

  EXPECT_EQ(2, read_count);
  EXPECT_EQ(ZX_ERR_PEER_CLOSED, h2.write(0, "\n", 1, nullptr, 0));
}

TEST(MessageReader, DoubleReentrantUnbind) {
  MessageReader reader;

  int read_count = 0;

  CallbackMessageHandler handler;
  handler.callback = [&reader, &read_count](HLCPPIncomingMessage message) {
    ++read_count;
    if (read_count == 1) {
      reader.WaitAndDispatchOneMessageUntil(zx::time::infinite());
    } else {
      reader.Unbind();
    }
    return ZX_OK;
  };

  reader.set_message_handler(&handler);

  fidl::test::AsyncLoopForTest loop;

  zx::channel h1, h2;
  EXPECT_EQ(ZX_OK, zx::channel::create(0, &h1, &h2));
  reader.Bind(std::move(h1));

  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg0, test_msg0_size, nullptr, 0));
  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg1, test_msg1_size, nullptr, 0));
  EXPECT_EQ(ZX_OK, h2.write(0, &test_msg2, test_msg2_size, nullptr, 0));
  ;

  EXPECT_TRUE(reader.is_bound());

  EXPECT_EQ(ZX_OK, loop.RunUntilIdle());

  EXPECT_FALSE(reader.is_bound());

  // The handler unbound the reader in a nested callstack, which means the
  // reader should have read two of the messages and its endpoint should be
  // closed.

  EXPECT_EQ(2, read_count);
  EXPECT_EQ(ZX_ERR_PEER_CLOSED, h2.write(0, "\n", 1, nullptr, 0));
}

TEST(MessageReader, ReentrantErrorHandler) {
  fidl::test::AsyncLoopForTest loop;

  fidl::test::misc::EchoPtr echo_ptr;
  EchoServer server(echo_ptr.NewRequest());

  echo_ptr.set_error_handler([](zx_status_t status) {});

  auto* echo_ptr_ptr = echo_ptr.get();
  echo_ptr_ptr->EchoString("Some string",
                           [echo_ptr = std::move(echo_ptr)](fidl::StringPtr echoed_value) {});
  server.Close();
  loop.RunUntilIdle();
}

TEST(MessageReader, Close) {
  fidl::test::AsyncLoopForTest loop;

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

  MessageReader client, server;
  client.Bind(std::move(h1));
  EXPECT_TRUE(client.is_bound());
  server.Bind(std::move(h2));
  EXPECT_TRUE(server.is_bound());

  zx_status_t error = 0;
  client.set_error_handler([&error](zx_status_t remote_error) { error = remote_error; });

  constexpr zx_status_t kSysError = 0xabDECADE;

  EXPECT_EQ(ZX_OK, server.Close(kSysError));
  EXPECT_FALSE(server.is_bound());

  // should only be able to call Close successfully once
  EXPECT_EQ(ZX_ERR_BAD_STATE, server.Close(kSysError));

  loop.RunUntilIdle();
  EXPECT_EQ(kSysError, error);
  EXPECT_FALSE(client.is_bound());
}

TEST(MessageReader, MagicNumberCheck) {
  fidl::test::AsyncLoopForTest loop;

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

  MessageReader reader;
  reader.Bind(std::move(h1));
  EXPECT_TRUE(reader.is_bound());

  zx_status_t error = 0;
  reader.set_error_handler([&error](zx_status_t remote_error) { error = remote_error; });
  EXPECT_TRUE(reader.has_error_handler());

  fidl_message_header_t header;
  header.magic_number = 0xFF;
  EXPECT_EQ(ZX_OK, writer.write(0, &header, sizeof(header), nullptr, 0));

  loop.RunUntilIdle();
  EXPECT_EQ(error, ZX_ERR_PROTOCOL_NOT_SUPPORTED);
}

}  // namespace
}  // namespace internal
}  // namespace fidl
