// 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 <fuchsia/hardware/pty/llcpp/fidl.h>
#include <fuchsia/io/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/sync/completion.h>
#include <lib/zx/time.h>

#include <algorithm>
#include <iterator>

#include <fs/managed_vfs.h>
#include <fs/vfs_types.h>
#include <zxtest/zxtest.h>

#include "pty-server-vnode.h"
#include "pty-server.h"

namespace {

using Connection = ::llcpp::fuchsia::hardware::pty::Device::SyncClient;

class PtyTestCase : public zxtest::Test {
 public:
  PtyTestCase()
      : loop_(&kAsyncLoopConfigNoAttachToCurrentThread),
        vfs_(loop_.dispatcher()),
        server_(zx::channel()) {}

  void SetUp() override {
    ASSERT_OK(loop_.StartThread("pty-test"));
    ASSERT_NO_FATAL_FAILURES(CreateNewServer(&server_));
  }
  void TearDown() override {
    sync_completion_t completion;
    vfs_.Shutdown([&completion](zx_status_t) { sync_completion_signal(&completion); });
    ASSERT_OK(sync_completion_wait_deadline(&completion, zx::time::infinite().get()));
  }

 protected:
  zx_status_t OpenClient(Connection* conn, uint32_t id, Connection* client) {
    zx::channel local, remote;
    zx_status_t status = zx::channel::create(0, &local, &remote);
    if (status != ZX_OK) {
      return status;
    }
    auto result = conn->OpenClient(id, std::move(remote));
    if (result.status() != ZX_OK) {
      return ZX_ERR_BAD_STATE;
    }
    if (result->s != ZX_OK) {
      return result->s;
    }
    *client = Connection(std::move(local));
    return ZX_OK;
  }

  async_dispatcher_t* dispatcher() { return loop_.dispatcher(); }
  fs::Vfs* vfs() { return &vfs_; }
  Connection take_server() { return std::move(server_); }

 private:
  void CreateNewServer(Connection* conn) {
    fbl::RefPtr<PtyServer> server;
    ASSERT_OK(PtyServer::Create(&server, &vfs_));
    auto vnode = fbl::MakeRefCounted<PtyServerVnode>(std::move(server));

    zx::channel local, remote;
    ASSERT_OK(zx::channel::create(0, &local, &remote));
    ASSERT_OK(
        vfs()->Serve(std::move(vnode), std::move(remote), fs::VnodeConnectionOptions::ReadWrite()));
    *conn = Connection(std::move(local));
  }

  async::Loop loop_;
  fs::ManagedVfs vfs_;
  Connection server_;
};

zx::eventpair GetEvent(Connection* conn) {
  auto result = conn->Describe();
  if (result.status() != ZX_OK) {
    return {};
  }
  zx::eventpair event = std::move(result->info.mutable_tty().event);
  return event;
}

void WriteCtrlC(Connection* conn) {
  uint8_t data[] = {0x03};
  auto result = conn->Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(data), std::size(data)});
  ASSERT_OK(result.status());
  ASSERT_OK(result->s);
  ASSERT_EQ(result->actual, std::size(data));
}

// Make sure the server connections describe appropriately
TEST_F(PtyTestCase, ServerDescribe) {
  Connection server{take_server()};
  auto result = server.Describe();
  ASSERT_OK(result.status());
  ASSERT_TRUE(result->info.is_tty());
  ASSERT_TRUE(result->info.tty().event.is_valid());
}  // namespace

TEST_F(PtyTestCase, ServerSetWindowSize) {
  Connection server{take_server()};
  auto result = server.SetWindowSize({.width = 80, .height = 24});
  ASSERT_OK(result.status());
  ASSERT_OK(result->status);
}  // namespace

TEST_F(PtyTestCase, ServerClrSetFeature) {
  Connection server{take_server()};
  auto result = server.ClrSetFeature(0, 0);
  ASSERT_OK(result.status());
  // ClrSetFeature is only meaningful on clients
  ASSERT_STATUS(result->status, ZX_ERR_NOT_SUPPORTED);
}

TEST_F(PtyTestCase, ServerGetWindowSize) {
  Connection server{take_server()};
  auto result = server.GetWindowSize();
  ASSERT_OK(result.status());
  // Our original implementation didn't support this, so preserve that behavior.
  // It's not clear why, though.  If this is causing problems, we should
  // probably just implement it.
  ASSERT_STATUS(result->status, ZX_ERR_NOT_SUPPORTED);
}

TEST_F(PtyTestCase, ServerMakeActive) {
  Connection server{take_server()};
  auto result = server.MakeActive(0);
  ASSERT_OK(result.status());
  // MakeActive is only meaningful on clients
  ASSERT_STATUS(result->status, ZX_ERR_NOT_SUPPORTED);
}

TEST_F(PtyTestCase, ServerReadEvents) {
  Connection server{take_server()};
  auto result = server.ReadEvents();
  ASSERT_OK(result.status());
  // ReadEvents is only meaningful on clients
  ASSERT_STATUS(result->status, ZX_ERR_NOT_SUPPORTED);
}

// Basic test of opening a client
TEST_F(PtyTestCase, ServerBasicOpenClient) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));

  // Make sure our client connection is valid after this
  ASSERT_STATUS(client.channel().wait_one(ZX_CHANNEL_PEER_CLOSED, zx::time{}, nullptr),
                ZX_ERR_TIMED_OUT);
}

// Try opening two clients with the same id
TEST_F(PtyTestCase, ServerOpenClientTwice) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));
  Connection client2{zx::channel{}};
  ASSERT_STATUS(OpenClient(&server, 0, &client2), ZX_ERR_INVALID_ARGS);

  // Our original client connection should still be good.
  ASSERT_STATUS(client.channel().wait_one(ZX_CHANNEL_PEER_CLOSED, zx::time{}, nullptr),
                ZX_ERR_TIMED_OUT);
}

// Try opening two clients with different ids
TEST_F(PtyTestCase, ServerOpenClientTwoDifferent) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));
  Connection client2{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client2));

  // Both connections should be good
  ASSERT_STATUS(client.channel().wait_one(ZX_CHANNEL_PEER_CLOSED, zx::time{}, nullptr),
                ZX_ERR_TIMED_OUT);
  ASSERT_STATUS(client2.channel().wait_one(ZX_CHANNEL_PEER_CLOSED, zx::time{}, nullptr),
                ZX_ERR_TIMED_OUT);
}

// Verify a server with no clients behaves as expected
TEST_F(PtyTestCase, ServerWithNoClientsInitialConditions) {
  Connection server{take_server()};
  zx::eventpair event = GetEvent(&server);

  auto check_state = [&]() {
    zx_signals_t observed = 0;
    ASSERT_STATUS(event.wait_one(0, zx::time{}, &observed), ZX_ERR_TIMED_OUT);
    // Precisely this set of signals should be asserted
    ASSERT_EQ(observed, ::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE |
                            ::llcpp::fuchsia::device::DEVICE_SIGNAL_HANGUP);

    // Attempts to read should get 0 bytes and ZX_OK
    {
      auto result = server.Read(10);
      ASSERT_OK(result.status());
      ASSERT_OK(result->s);
      ASSERT_EQ(result->data.count(), 0);
    }

    // Attempts to write should fail with ZX_ERR_PEER_CLOSED
    {
      uint8_t data[16] = {};
      auto result =
          server.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(data), std::size(data)});
      ASSERT_OK(result.status());
      ASSERT_STATUS(result->s, ZX_ERR_PEER_CLOSED);
    }
  };

  ASSERT_NO_FATAL_FAILURES(check_state());

  // Create a client and close it, then make sure we're back in the initial
  // state
  {
    Connection client{zx::channel{}};
    ASSERT_OK(OpenClient(&server, 1, &client));
  }
  // Wait for the server to signal that it got the client disconnect
  ASSERT_OK(event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_HANGUP, zx::time::infinite(),
                           nullptr));

  ASSERT_NO_FATAL_FAILURES(check_state());
}

// Verify a server with a client has the right state
TEST_F(PtyTestCase, ServerWithClientInitialConditions) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));

  zx::eventpair server_event = GetEvent(&server);
  zx::eventpair client_event = GetEvent(&client);

  zx_signals_t observed = 0;
  ASSERT_STATUS(server_event.wait_one(0, zx::time{}, &observed), ZX_ERR_TIMED_OUT);
  ASSERT_EQ(observed, ::llcpp::fuchsia::device::DEVICE_SIGNAL_WRITABLE);

  observed = 0;
  ASSERT_STATUS(client_event.wait_one(0, zx::time{}, &observed), ZX_ERR_TIMED_OUT);
  ASSERT_EQ(observed, ::llcpp::fuchsia::device::DEVICE_SIGNAL_WRITABLE);

  // Attempts to read on either side should get SHOULD_WAIT
  {
    auto result = server.Read(10);
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->s, ZX_ERR_SHOULD_WAIT);
  }
  {
    auto result = client.Read(10);
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->s, ZX_ERR_SHOULD_WAIT);
  }

  // Client should be in cooked mode
  {
    auto result = client.ClrSetFeature(0, 0);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->features, 0);
  }
}

// Verify a read from a server for 0 bytes doesn't return ZX_ERR_SHOULD_WAIT
TEST_F(PtyTestCase, ServerEmpty0ByteRead) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));

  auto result = server.Read(0);
  ASSERT_OK(result.status());
  ASSERT_OK(result->s);
  ASSERT_EQ(result->data.count(), 0);
}

// Verify a write by the server for 0 bytes when the receiving client is full doesn't return
// ZX_ERR_SHOULD_WAIT
TEST_F(PtyTestCase, ClientFull0ByteServerWrite) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));

  // Fill up FIFO
  while (true) {
    uint8_t buf[256] = {};
    auto result = server.Write({fidl::unowned_ptr(buf), std::size(buf)});
    ASSERT_OK(result.status());
    if (result->s == ZX_ERR_SHOULD_WAIT) {
      break;
    }
    ASSERT_OK(result->s);
    ASSERT_GT(result->actual, 0);
  }

  auto result = server.Write({});
  ASSERT_OK(result.status());
  ASSERT_OK(result->s);
  ASSERT_EQ(result->actual, 0);
}

// Verify a write by a client for 0 bytes when the client isn't active returns
// ZX_ERR_SHOULD_WAIT
TEST_F(PtyTestCase, ClientInactive0ByteClientWrite) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));
  Connection inactive_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &inactive_client));

  auto result = inactive_client.Write({});
  ASSERT_OK(result.status());
  ASSERT_STATUS(result->s, ZX_ERR_SHOULD_WAIT);
}

// Make sure the client connections describe appropriately
TEST_F(PtyTestCase, ClientDescribe) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));

  auto result = client.Describe();
  ASSERT_OK(result.status());
  ASSERT_TRUE(result->info.is_tty());
  ASSERT_TRUE(result->info.tty().event.is_valid());
}

TEST_F(PtyTestCase, ClientWindowSize) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));

  {
    auto result = server.SetWindowSize({.width = 80, .height = 24});
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
  }
  {
    auto result = client.GetWindowSize();
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->size.width, 80);
    ASSERT_EQ(result->size.height, 24);
  }
  {
    auto result = client.SetWindowSize({.width = 5, .height = 32});
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
  }
  {
    auto result = client.GetWindowSize();
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->size.width, 5);
    ASSERT_EQ(result->size.height, 32);
  }
}

TEST_F(PtyTestCase, ClientClrSetFeature) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));

  {
    auto result = client.ClrSetFeature(0, 0);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->features, 0);
  }

  // Make sure we can set bits
  {
    auto result = client.ClrSetFeature(0, ::llcpp::fuchsia::hardware::pty::FEATURE_RAW);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->features, ::llcpp::fuchsia::hardware::pty::FEATURE_RAW);
  }

  // If we don't change any bits, we should see the new settings
  {
    auto result = client.ClrSetFeature(0, 0);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->features, ::llcpp::fuchsia::hardware::pty::FEATURE_RAW);
  }

  // Make sure we can clear bits
  {
    auto result = client.ClrSetFeature(::llcpp::fuchsia::hardware::pty::FEATURE_RAW, 0);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->features, 0);
  }
}

TEST_F(PtyTestCase, ClientClrSetFeatureInvalidBit) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));

  {
    auto result = client.ClrSetFeature(0, 0x2);
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->status, ZX_ERR_NOT_SUPPORTED);
    ASSERT_EQ(result->features, 0);
  }

  {
    auto result = client.ClrSetFeature(0x2, 0);
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->status, ZX_ERR_NOT_SUPPORTED);
    ASSERT_EQ(result->features, 0);
  }
}

TEST_F(PtyTestCase, ClientGetWindowSizeServerNeverSet) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));

  auto result = client.GetWindowSize();
  ASSERT_OK(result.status());
  ASSERT_OK(result->status);
  ASSERT_EQ(result->size.width, 0);
  ASSERT_EQ(result->size.height, 0);
}

// Each client should have its own feature flags
TEST_F(PtyTestCase, ClientIndependentFeatureFlags) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));
  Connection client2{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client2));

  {
    auto result = client.ClrSetFeature(0, ::llcpp::fuchsia::hardware::pty::FEATURE_RAW);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->features, ::llcpp::fuchsia::hardware::pty::FEATURE_RAW);
  }

  {
    // Client 2 shouldn't see the changes
    auto result = client2.ClrSetFeature(0, 0);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->features, 0);
  }
}

TEST_F(PtyTestCase, ClientMakeActive) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));
  Connection client2{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client2));

  {
    auto result = client.MakeActive(0);
    ASSERT_OK(result.status());
    // This client is not the controlling client (id=0), so it cannot change the
    // active client
    ASSERT_STATUS(result->status, ZX_ERR_ACCESS_DENIED);
  }
  {
    auto result = client2.MakeActive(1);
    ASSERT_OK(result.status());
    // This client is the controlling client (id=0), so it can.
    ASSERT_OK(result->status);
  }
  {
    // Changing the active client to the existing active client should be fine
    auto result = client2.MakeActive(1);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
  }
  {
    // Changing the active client to the control client should be fine
    auto result = client2.MakeActive(0);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
  }
  {
    // Changing the active client to a non-existent client should fail
    auto result = client2.MakeActive(2);
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->status, ZX_ERR_NOT_FOUND);
  }
}

TEST_F(PtyTestCase, ClientReadEvents) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));
  Connection client2{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client2));

  {
    auto result = client.ReadEvents();
    ASSERT_OK(result.status());
    // This client is not the controlling client (id=0), so it cannot read events
    ASSERT_STATUS(result->status, ZX_ERR_ACCESS_DENIED);
  }

  {
    auto result = client2.ReadEvents();
    ASSERT_OK(result.status());
    // This client is the controlling client (id=0), so it can read events
    ASSERT_OK(result->status);
    ASSERT_EQ(result->events, 0);
  }
}

// Reading events should clear the event condition
TEST_F(PtyTestCase, ClientReadEventsClears) {
  Connection server{take_server()};
  Connection active_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &active_client));
  Connection control_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &control_client));

  zx::eventpair control_event = GetEvent(&control_client);

  // No events yet
  ASSERT_STATUS(
      control_event.wait_one(::llcpp::fuchsia::hardware::pty::SIGNAL_EVENT, zx::time{}, nullptr),
      ZX_ERR_TIMED_OUT);

  // Write a ^C byte from the server to trigger a cooked-mode event
  ASSERT_NO_FATAL_FAILURES(WriteCtrlC(&server));

  ASSERT_OK(control_event.wait_one(::llcpp::fuchsia::hardware::pty::SIGNAL_EVENT,
                                   zx::time::infinite(), nullptr));

  {
    auto result = control_client.ReadEvents();
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->events, ::llcpp::fuchsia::hardware::pty::EVENT_INTERRUPT);
  }

  // Signal should have cleared
  ASSERT_STATUS(
      control_event.wait_one(::llcpp::fuchsia::hardware::pty::SIGNAL_EVENT, zx::time{}, nullptr),
      ZX_ERR_TIMED_OUT);

  // Event should have cleared
  {
    auto result = control_client.ReadEvents();
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->events, 0);
  }
}

// Events arrive even without a controlling client connected
TEST_F(PtyTestCase, EventsSentWithNoControllingClient) {
  Connection server{take_server()};
  Connection active_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &active_client));

  // Write a ^C byte from the server to trigger a cooked-mode event
  ASSERT_NO_FATAL_FAILURES(WriteCtrlC(&server));

  // Connect a control client to inspect the event
  Connection control_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &control_client));

  zx::eventpair control_event = GetEvent(&control_client);
  ASSERT_OK(
      control_event.wait_one(::llcpp::fuchsia::hardware::pty::SIGNAL_EVENT, zx::time{}, nullptr));

  {
    auto result = control_client.ReadEvents();
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->events, ::llcpp::fuchsia::hardware::pty::EVENT_INTERRUPT);
  }
}

TEST_F(PtyTestCase, NonControllingClientOpenClient) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));

  Connection client2{zx::channel{}};
  // This client is not the controlling client (id=0), so it cannot create new
  // clients
  ASSERT_STATUS(OpenClient(&client, 2, &client2), ZX_ERR_ACCESS_DENIED);
}

TEST_F(PtyTestCase, ControllingClientOpenClient) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));

  Connection client2{zx::channel{}};
  ASSERT_OK(OpenClient(&client, 1, &client2));
}

TEST_F(PtyTestCase, ActiveClientCloses) {
  Connection server{take_server()};
  Connection control_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &control_client));
  {
    Connection active_client{zx::channel{}};
    ASSERT_OK(OpenClient(&server, 1, &active_client));
    auto result = control_client.MakeActive(1);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
  }

  zx::eventpair control_event = GetEvent(&control_client);
  zx_signals_t observed = 0;
  ASSERT_OK(control_event.wait_one(::llcpp::fuchsia::hardware::pty::SIGNAL_EVENT,
                                   zx::time::infinite(), &observed));
  // Wait again with no timeout, so that observed doesn't have any transient
  // signals in it.
  ASSERT_OK(control_event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_HANGUP, zx::time{},
                                   &observed));
  ASSERT_EQ(observed, ::llcpp::fuchsia::hardware::pty::SIGNAL_EVENT |
                          ::llcpp::fuchsia::device::DEVICE_SIGNAL_HANGUP);

  auto result = control_client.ReadEvents();
  ASSERT_OK(result.status());
  ASSERT_OK(result->status);
  ASSERT_EQ(result->events, ::llcpp::fuchsia::hardware::pty::EVENT_HANGUP);
}

// Makes sure nothing goes wrong when the active client is the controling
// client and it closes.
TEST_F(PtyTestCase, ActiveClientClosesWhenControl) {
  Connection server{take_server()};
  {
    Connection control_client{zx::channel{}};
    ASSERT_OK(OpenClient(&server, 0, &control_client));
  }
  zx::eventpair event = GetEvent(&server);
  zx_signals_t observed = 0;
  ASSERT_OK(event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_HANGUP, zx::time::infinite(),
                           &observed));
}

TEST_F(PtyTestCase, ServerClosesWhenClientPresent) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &client));

  // Write some data to the client, so we can verify the client can drain the
  // buffer still.

  uint8_t kTestData[] = u8"hello world";
  {
    auto result =
        server.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(kTestData), std::size(kTestData)});
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->actual, std::size(kTestData));
  }

  server.mutable_channel()->reset();

  zx::eventpair event = GetEvent(&client);
  zx_signals_t observed = 0;
  ASSERT_OK(event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_HANGUP, zx::time::infinite(),
                           &observed));
  // Wait again with no timeout, so that observed doesn't have any transient
  // signals in it.
  ASSERT_OK(event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_HANGUP, zx::time{}, &observed));
  ASSERT_EQ(observed, ::llcpp::fuchsia::device::DEVICE_SIGNAL_HANGUP |
                          ::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE);

  {
    auto result = client.ReadEvents();
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->events, ::llcpp::fuchsia::hardware::pty::EVENT_HANGUP);
  }

  // Attempts to drain the buffer should succeed
  {
    // Request more bytes than are present
    auto result = client.Read(std::size(kTestData) + 10);
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->data.count(), std::size(kTestData));
    ASSERT_BYTES_EQ(result->data.data(), kTestData, std::size(kTestData));
  }

  // Attempts to read the empty buffer should fail with ZX_ERR_PEER_CLOSED
  {
    auto result = client.Read(10);
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->s, ZX_ERR_PEER_CLOSED);
  }

  // Attempts to write should fail with ZX_ERR_PEER_CLOSED
  {
    uint8_t data[16] = {};
    auto result = client.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(data), std::size(data)});
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->s, ZX_ERR_PEER_CLOSED);
  }
}

// Test writes from the client to the server when the client is cooked
TEST_F(PtyTestCase, ServerReadClientCooked) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));

  // In cooked mode, client writes should have \n transformed to \r\n, and
  // control chars untouched.
  uint8_t kTestData[] = u8"hello\x03 world\ntest message\n";
  const uint8_t kExpectedReadback[] = u8"hello\x03 world\r\ntest message\r\n";
  {
    auto result =
        client.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(kTestData), std::size(kTestData)});
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->actual, std::size(kTestData));
  }

  zx::eventpair event = GetEvent(&server);
  ASSERT_OK(event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time::infinite(),
                           nullptr));
  {
    auto result = server.Read(std::size(kExpectedReadback) + 10);
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->data.count(), std::size(kExpectedReadback));
    ASSERT_BYTES_EQ(result->data.data(), kExpectedReadback, std::size(kExpectedReadback));
  }
  // Nothing left to read
  ASSERT_STATUS(
      event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{}, nullptr),
      ZX_ERR_TIMED_OUT);
}

// Test writes from the server to the client when the client is cooked
TEST_F(PtyTestCase, ServerWriteClientCooked) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));

  // In cooked mode, server writes should have newlines untouched and control
  // chars should cause a short write
  uint8_t kTestData[] = u8"hello world\ntest\x03 message\n";
  // We expect to read this back, but without the trailing nul
  const uint8_t kExpectedReadbackWithNul[] = u8"hello world\ntest";
  {
    auto result =
        server.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(kTestData), std::size(kTestData)});
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    // We expect to see the written count to include the ^C
    ASSERT_EQ(result->actual, std::size(kExpectedReadbackWithNul) - 1 + 1);
  }

  zx::eventpair event = GetEvent(&client);
  ASSERT_OK(event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time::infinite(),
                           nullptr));
  {
    auto result = client.Read(std::size(kExpectedReadbackWithNul) + 10);
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->data.count(), std::size(kExpectedReadbackWithNul) - 1);
    ASSERT_BYTES_EQ(result->data.data(), kExpectedReadbackWithNul,
                    std::size(kExpectedReadbackWithNul) - 1);
  }
  // Nothing left to read
  ASSERT_STATUS(
      event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{}, nullptr),
      ZX_ERR_TIMED_OUT);
}

// Test writes from the client to the server when the client is raw
TEST_F(PtyTestCase, ServerReadClientRaw) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));

  {
    auto result = client.ClrSetFeature(0, ::llcpp::fuchsia::hardware::pty::FEATURE_RAW);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
  }

  // In raw mode, client writes should be untouched.
  uint8_t kTestData[] = u8"hello\x03 world\ntest message\n";
  {
    auto result =
        client.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(kTestData), std::size(kTestData)});
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->actual, std::size(kTestData));
  }

  zx::eventpair event = GetEvent(&server);
  ASSERT_OK(event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time::infinite(),
                           nullptr));
  {
    auto result = server.Read(std::size(kTestData) + 10);
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->data.count(), std::size(kTestData));
    ASSERT_BYTES_EQ(result->data.data(), kTestData, std::size(kTestData));
  }
  // Nothing left to read
  ASSERT_STATUS(
      event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{}, nullptr),
      ZX_ERR_TIMED_OUT);
}

// Test writes from the server to the client when the client is raw
TEST_F(PtyTestCase, ServerWriteClientRaw) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));
  Connection control_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &control_client));

  {
    auto result = client.ClrSetFeature(0, ::llcpp::fuchsia::hardware::pty::FEATURE_RAW);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
  }

  // In raw mode, server writes should be untouched.
  uint8_t kTestData[] = u8"hello world\ntest\x03 message\n";
  {
    auto result =
        server.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(kTestData), std::size(kTestData)});
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->actual, std::size(kTestData));
  }

  zx::eventpair event = GetEvent(&client);
  ASSERT_OK(event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time::infinite(),
                           nullptr));
  {
    auto result = client.Read(std::size(kTestData) + 10);
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->data.count(), std::size(kTestData));
    ASSERT_BYTES_EQ(result->data.data(), kTestData, std::size(kTestData));
  }
  // Nothing left to read
  ASSERT_STATUS(
      event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{}, nullptr),
      ZX_ERR_TIMED_OUT);

  // Make sure we didn't see an INTERRUPT_EVENT.
  {
    auto result = control_client.ReadEvents();
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
    ASSERT_EQ(result->events, 0);
  }
}

TEST_F(PtyTestCase, ServerFillsClientFifo) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));

  zx::eventpair server_event = GetEvent(&server);
  zx::eventpair client_event = GetEvent(&client);

  uint8_t kTestString[] = "abcdefghijklmnopqrstuvwxyz";
  size_t total_written = 0;
  while (server_event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_WRITABLE, zx::time{},
                               nullptr) == ZX_OK) {
    auto result = server.Write(
        fidl::VectorView<uint8_t>{fidl::unowned_ptr(kTestString), std::size(kTestString) - 1});
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_GT(result->actual, 0);
    total_written += result->actual;
  }

  // Trying to write when full gets SHOULD_WAIT
  {
    auto result = server.Write(
        fidl::VectorView<uint8_t>{fidl::unowned_ptr(kTestString), std::size(kTestString) - 1});
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->s, ZX_ERR_SHOULD_WAIT);
  }

  // Client can read FIFO contents back out
  size_t total_read = 0;
  while (total_read < total_written) {
    ASSERT_OK(client_event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{},
                                    nullptr));
    auto result = client.Read(std::size(kTestString) - 1);
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->data.count(),
              std::min(std::size(kTestString) - 1, total_written - total_read));
    ASSERT_BYTES_EQ(result->data.data(), kTestString, result->data.count());
    total_read += result->data.count();
  }

  ASSERT_STATUS(
      client_event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{}, nullptr),
      ZX_ERR_TIMED_OUT);
}

TEST_F(PtyTestCase, ClientFillsServerFifo) {
  Connection server{take_server()};
  Connection client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &client));

  zx::eventpair server_event = GetEvent(&server);
  zx::eventpair client_event = GetEvent(&client);

  uint8_t kTestString[] = "abcdefghijklmnopqrstuvwxyz";
  size_t total_written = 0;
  while (client_event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_WRITABLE, zx::time{},
                               nullptr) == ZX_OK) {
    auto result = client.Write(
        fidl::VectorView<uint8_t>{fidl::unowned_ptr(kTestString), std::size(kTestString) - 1});
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_GT(result->actual, 0);
    total_written += result->actual;
  }

  // Trying to write when full gets SHOULD_WAIT
  {
    auto result = client.Write(
        fidl::VectorView<uint8_t>{fidl::unowned_ptr(kTestString), std::size(kTestString) - 1});
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->s, ZX_ERR_SHOULD_WAIT);
  }

  // Server can read FIFO contents back out
  size_t total_read = 0;
  while (total_read < total_written) {
    ASSERT_OK(server_event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{},
                                    nullptr));
    auto result = server.Read(std::size(kTestString) - 1);
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->data.count(),
              std::min(std::size(kTestString) - 1, total_written - total_read));
    ASSERT_BYTES_EQ(result->data.data(), kTestString, result->data.count());
    total_read += result->data.count();
  }

  ASSERT_STATUS(
      server_event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{}, nullptr),
      ZX_ERR_TIMED_OUT);
}

TEST_F(PtyTestCase, NonActiveClientsCantWrite) {
  Connection server{take_server()};
  Connection control_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &control_client));
  Connection other_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &other_client));

  // control_client is the current active

  zx::eventpair event = GetEvent(&other_client);
  zx_signals_t observed = 0;
  ASSERT_STATUS(event.wait_one(0, zx::time{}, &observed), ZX_ERR_TIMED_OUT);
  ASSERT_FALSE(observed & ::llcpp::fuchsia::device::DEVICE_SIGNAL_WRITABLE);
  {
    uint8_t byte = 0;
    auto result = other_client.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(&byte), 1});
    ASSERT_OK(result.status());
    ASSERT_STATUS(result->s, ZX_ERR_SHOULD_WAIT);
  }
}

TEST_F(PtyTestCase, ClientsHaveIndependentFifos) {
  Connection server{take_server()};
  Connection control_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 0, &control_client));
  Connection other_client{zx::channel{}};
  ASSERT_OK(OpenClient(&server, 1, &other_client));

  uint8_t kControlClientByte = 1;
  uint8_t kOtherClientByte = 2;

  // control_client is the current active, so it should go to its FIFO
  {
    auto result =
        server.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(&kControlClientByte), 1});
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->actual, 1);
  }

  // Switch active clients
  {
    auto result = control_client.MakeActive(1);
    ASSERT_OK(result.status());
    ASSERT_OK(result->status);
  }

  // This should go to the other client's FIFO
  {
    auto result = server.Write(fidl::VectorView<uint8_t>{fidl::unowned_ptr(&kOtherClientByte), 1});
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->actual, 1);
  }

  auto check_client = [&](Connection* client, uint8_t expected_value) {
    zx::eventpair event = GetEvent(client);

    ASSERT_OK(
        event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{}, nullptr));

    auto result = client->Read(10);
    ASSERT_OK(result.status());
    ASSERT_OK(result->s);
    ASSERT_EQ(result->data.count(), 1);
    ASSERT_EQ(result->data.data()[0], expected_value);

    ASSERT_STATUS(
        event.wait_one(::llcpp::fuchsia::device::DEVICE_SIGNAL_READABLE, zx::time{}, nullptr),
        ZX_ERR_TIMED_OUT);
  };

  ASSERT_NO_FATAL_FAILURES(check_client(&other_client, kOtherClientByte));
  ASSERT_NO_FATAL_FAILURES(check_client(&control_client, kControlClientByte));
}

}  // namespace
