// 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 "serial-ppp.h"

#include <lib/fzl/vmo-mapper.h>
#include <lib/stdcompat/optional.h>
#include <lib/zx/event.h>
#include <lib/zx/socket.h>
#include <zircon/errors.h>

#include <iomanip>
#include <sstream>

#include <fbl/span.h>
#include <zxtest/zxtest.h>

#include "lib/common/ppp.h"

namespace {

namespace netdev = fuchsia_hardware_network;

class SerialPppHarness : public zxtest::Test {
 public:
  static constexpr uint32_t kEventStatusChanged = ZX_USER_SIGNAL_0;
  static constexpr uint32_t kEventRxCompleted = ZX_USER_SIGNAL_1;
  static constexpr uint32_t kEventTxCompleted = ZX_USER_SIGNAL_2;
  static constexpr uint8_t kVmoId = 0;
  static constexpr uint64_t kDefaultBufferReservation = 2048;

  static constexpr uint64_t kVmoSize = ppp::SerialPpp::kFifoDepth * 2 * ZX_PAGE_SIZE;
  void SetUp() override {
    zx::vmo device_vmo;
    ASSERT_OK(zx::vmo::create(kVmoSize, 0, &device_vmo));
    ASSERT_OK(vmo_.Map(device_vmo, 0, kVmoSize, ZX_VM_PERM_READ | ZX_VM_PERM_WRITE));
    ASSERT_OK(zx::event::create(0, &event_));

    serial_proto_ops_ = serial_protocol_ops_t{
        .get_info = [](void* ctx, serial_port_info_t* out_info) { return ZX_ERR_NOT_SUPPORTED; },
        .config = [](void* ctx, uint32_t baud_rate,
                     uint32_t flags) { return ZX_ERR_NOT_SUPPORTED; },
        .open_socket =
            [](void* ctx, zx_handle_t* out_handle) {
              return static_cast<SerialPppHarness*>(ctx)->OpenSocket(out_handle);
            }};

    serial_protocol_t proto = {
        .ops = &serial_proto_ops_,
        .ctx = this,
    };

    device_ = std::make_unique<ppp::SerialPpp>(nullptr, ddk::SerialProtocolClient(&proto));
    // Disable rx timeouts by default to prevent flakes.
    device_->set_enable_rx_timeout(false);

    netdevice_proto_ops_ = network_device_ifc_protocol_ops_t{
        .status_changed =
            [](void* ctx, const status_t* new_status) {
              auto self = static_cast<SerialPppHarness*>(ctx);
              fbl::AutoLock lock(&self->lock_);
              self->status_ = *new_status;
              EXPECT_OK(self->event_.signal(0, kEventStatusChanged));
            },
        .complete_rx =
            [](void* ctx, const rx_buffer_t* rx_list, size_t rx_count) {
              auto self = static_cast<SerialPppHarness*>(ctx);
              fbl::AutoLock lock(&self->lock_);
              for (auto buffer : fbl::Span(rx_list, rx_count)) {
                self->rx_completed_.push(buffer);
              }
              EXPECT_OK(self->event_.signal(0, kEventRxCompleted));
            },
        .complete_tx =
            [](void* ctx, const tx_result_t* tx_list, size_t tx_count) {
              auto self = static_cast<SerialPppHarness*>(ctx);
              fbl::AutoLock lock(&self->lock_);
              for (auto buffer : fbl::Span(tx_list, tx_count)) {
                self->tx_completed_.push(buffer);
              }
              EXPECT_OK(self->event_.signal(0, kEventTxCompleted));
            },
        .snoop = nullptr};
    network_device_ifc_protocol_t netdev_proto = {.ops = &netdevice_proto_ops_, .ctx = this};
    ASSERT_OK(device_->NetworkDeviceImplInit(&netdev_proto));

    device_->NetworkDeviceImplPrepareVmo(kVmoId, std::move(device_vmo));
    // NB: We're assuming starting is synchronous here.
    device_->NetworkDeviceImplStart([](void* cookie) {}, nullptr);
  }

  zx_status_t OpenSocket(zx_handle_t* out) {
    zx::socket driver_socket;
    zx_status_t status = zx::socket::create(ZX_SOCKET_STREAM, &driver_socket, &socket_);
    EXPECT_OK(status);
    if (status == ZX_OK) {
      *out = driver_socket.release();
    }
    return status;
  }

  void Tx(uint32_t id, uint64_t offset, netdev::wire::FrameType type,
          fbl::Span<const uint8_t> data) {
    std::copy(data.begin(), data.end(), vmo_data().subspan(offset).begin());
    buffer_region_t part = {
        .offset = offset,
        .length = data.size(),
    };
    tx_buffer_t buffer = {
        .id = id,
        .data =
            {
                .vmo_id = kVmoId,
                .parts_list = &part,
                .parts_count = 1,
            },
        .meta =
            {
                .info = frame_info_t{},
                .info_type = 0,
                .flags = 0,
                .frame_type = static_cast<uint8_t>(type),
            },
        .head_length = 0,
        .tail_length = 0,
    };
    device_->NetworkDeviceImplQueueTx(&buffer, 1);
  }

  void PushRxSpace(uint32_t id, uint64_t offset, uint64_t length = kDefaultBufferReservation) {
    buffer_region_t part = {.offset = offset, .length = length};
    rx_space_buffer_t space = {
        .id = id,
        .data = {.vmo_id = kVmoId, .parts_list = &part, .parts_count = 1},
    };
    device_->NetworkDeviceImplQueueRxSpace(&space, 1);
  }

  fbl::Span<uint8_t> vmo_data() {
    return fbl::Span<uint8_t>(static_cast<uint8_t*>(vmo_.start()), kVmoSize);
  }

  void TearDown() override { device_->Shutdown(); }

  zx_status_t Wait(zx_signals_t signals, zx::time deadline = zx::time::infinite()) {
    zx_status_t status = event_.wait_one(signals, deadline, nullptr);
    if (status == ZX_OK) {
      status = event_.signal(signals, 0);
    }
    return status;
  }

  ppp::SerialPpp& Device() { return *device_; }
  zx::event& Event() { return event_; }
  zx::socket& Socket() { return socket_; }

  cpp17::optional<rx_buffer_t> PopRx() {
    fbl::AutoLock lock(&lock_);
    if (rx_completed_.empty()) {
      return cpp17::nullopt;
    }
    rx_buffer_t ret = rx_completed_.front();
    rx_completed_.pop();
    return ret;
  }

  fit::result<rx_buffer_t, zx_status_t> WaitRx() {
    for (;;) {
      auto buffer = PopRx();
      if (buffer.has_value()) {
        return fit::ok(*buffer);
      }
      zx_status_t status = Wait(kEventRxCompleted);
      if (status != ZX_OK) {
        return fit::error(status);
      }
    }
  }

  cpp17::optional<tx_result_t> PopTx() {
    fbl::AutoLock lock(&lock_);
    if (tx_completed_.empty()) {
      return cpp17::nullopt;
    }
    tx_result_t ret = tx_completed_.front();
    tx_completed_.pop();
    return ret;
  }

  std::queue<rx_buffer_t> PopAllRxAndClearEvent() {
    fbl::AutoLock lock(&lock_);
    auto ret = std::move(rx_completed_);
    rx_completed_ = {};
    EXPECT_OK(event_.signal(kEventRxCompleted, 0));
    return ret;
  }

  std::queue<tx_result_t> PopAllTxAndClearEvent() {
    fbl::AutoLock lock(&lock_);
    auto ret = std::move(tx_completed_);
    tx_completed_ = {};
    EXPECT_OK(event_.signal(kEventTxCompleted, 0));
    return ret;
  }

  cpp17::optional<status_t> TakeStatus() {
    fbl::AutoLock lock(&lock_);
    auto ret = status_;
    status_.reset();
    return ret;
  }

 private:
  std::unique_ptr<ppp::SerialPpp> device_;
  zx::socket socket_;
  serial_protocol_ops_t serial_proto_ops_;
  network_device_ifc_protocol_ops_t netdevice_proto_ops_;
  zx::event event_;

  fbl::Mutex lock_;
  cpp17::optional<status_t> status_ __TA_GUARDED(lock_);
  std::queue<rx_buffer_t> rx_completed_ __TA_GUARDED(lock_);
  std::queue<tx_result_t> tx_completed_ __TA_GUARDED(lock_);
  fzl::VmoMapper vmo_;
};

TEST_F(SerialPppHarness, DriverTx) {
  std::string information = "Hello\x7eworld!";
  fbl::Span<const uint8_t> span(reinterpret_cast<const uint8_t*>(information.data()),
                                information.size());
  Tx(0, 0, netdev::wire::FrameType::kIpv4, span);
  ASSERT_OK(Wait(kEventTxCompleted));
  const std::vector<uint8_t> expect = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x21, 'H', 'e',  'l',  'l',  'o',
      0x7d, 0x5e, 'w',  'o',  'r',  'l',  'd',  '!', 0x28, 0x67, 0x7e,
  };
  std::vector<uint8_t> buffer(expect.size() * 2);
  size_t actual = 0;
  ASSERT_OK(Socket().read(0, buffer.data(), buffer.size(), &actual));
  ASSERT_EQ(actual, expect.size());
  ASSERT_BYTES_EQ(buffer.data(), expect.data(), expect.size());
}

TEST_F(SerialPppHarness, DriverMultipleTx) {
  std::string information = "Hello\x7eworld!";
  fbl::Span<const uint8_t> span(reinterpret_cast<const uint8_t*>(information.data()),
                                information.size());
  constexpr uint32_t kFrameCount = 5;
  for (uint32_t i = 0; i < kFrameCount; i++) {
    Tx(i, i * kDefaultBufferReservation, netdev::wire::FrameType::kIpv4, span);
  }

  const std::vector<uint8_t> expect = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x21, 'H', 'e',  'l',  'l',  'o',
      0x7d, 0x5e, 'w',  'o',  'r',  'l',  'd',  '!', 0x28, 0x67, 0x7e,
  };
  std::vector<uint8_t> buffer(expect.size() * kFrameCount);
  size_t read = 0;
  while (read < buffer.size()) {
    ASSERT_OK(Socket().wait_one(ZX_SOCKET_READABLE, zx::time::infinite(), nullptr));
    size_t actual;
    ASSERT_OK(Socket().read(0, &buffer[read], buffer.size() - read, &actual));
    read += actual;
  }
  for (uint32_t i = 0; i < kFrameCount; i++) {
    ASSERT_BYTES_EQ(&buffer[i * expect.size()], expect.data(), expect.size(), "frame %d", i);
  }
}

TEST_F(SerialPppHarness, DriverTxEscapedFcs) {
  // I stumbled upon a string that has a flag sequence in its FCS. Thus this
  // test is able to exist.
  std::string information = "\x29Hello\x7eworld!";
  fbl::Span<const uint8_t> span(reinterpret_cast<const uint8_t*>(information.data()),
                                information.size());
  Tx(0, 0, netdev::wire::FrameType::kIpv4, span);
  ASSERT_OK(Wait(kEventTxCompleted));
  auto tx_result = PopTx();
  ASSERT_TRUE(tx_result.has_value());
  ASSERT_OK(tx_result->status);
  ASSERT_EQ(tx_result->id, 0);
  const std::vector<uint8_t> expect = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x21, 0x29, 'H',  'e',  'l',  'l',  'o',
      0x7d, 0x5e, 'w',  'o',  'r',  'l',  'd',  '!',  0x7d, 0x3c, 0x83, 0x7e,
  };
  std::vector<uint8_t> buffer(expect.size() * 2);
  size_t actual = 0;
  ASSERT_OK(Socket().read(0, buffer.data(), buffer.size(), &actual));
  ASSERT_EQ(actual, expect.size());
  ASSERT_BYTES_EQ(buffer.data(), expect.data(), expect.size());
}

TEST_F(SerialPppHarness, DriverTxEmpty) {
  std::string information;
  fbl::Span<const uint8_t> span(reinterpret_cast<const uint8_t*>(information.data()),
                                information.size());
  Tx(0, 0, netdev::wire::FrameType::kIpv6, span);
  ASSERT_OK(Wait(kEventTxCompleted));
  auto tx_result = PopTx();
  ASSERT_TRUE(tx_result.has_value());
  ASSERT_OK(tx_result->status);
  ASSERT_EQ(tx_result->id, 0);
  const std::vector<uint8_t> expect = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x57, 0x52, 0xf0, 0x7e,
  };
  std::vector<uint8_t> buffer(expect.size() * 2);
  size_t actual = 0;
  ASSERT_OK(Socket().read(0, buffer.data(), buffer.size(), &actual));
  ASSERT_EQ(actual, expect.size());
  ASSERT_BYTES_EQ(buffer.data(), expect.data(), expect.size());
}

TEST_F(SerialPppHarness, DriverRxIgnoresUnknownProtocols) {
  PushRxSpace(0, 0, kDefaultBufferReservation);
  std::string information = "\x80\x21Hello\x7eworld!";
  const std::vector<uint8_t> serial_data = {
      0x7e, 0xff, 0x7d, 0x23, 0x80, 0x21, 'H', 'e', 'l',  'l',  'o',
      0x7d, 0x5e, 'w',  'o',  'r',  'l',  'd', '!', 0xf6, 0xe1, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data.data(), serial_data.size(), &actual));
  ASSERT_EQ(actual, serial_data.size());
  ASSERT_STATUS(Wait(kEventRxCompleted, zx::deadline_after(zx::msec(20))), ZX_ERR_TIMED_OUT);
}

TEST_F(SerialPppHarness, DriverRxSingleFrame) {
  PushRxSpace(0, 0);
  std::string information = "Some Ipv4";
  const std::vector<uint8_t> serial_data = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x21, 'S',  'o',  'm',
      'e',  ' ',  'I',  'p',  'v',  '4',  0xae, 0xdf, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data.data(), serial_data.size(), &actual));
  ASSERT_EQ(actual, serial_data.size());
  ASSERT_OK(Wait(kEventRxCompleted));
  auto rx_buffer = PopRx();
  ASSERT_TRUE(rx_buffer.has_value());
  ASSERT_EQ(rx_buffer->meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv4));
  auto rx_data = vmo_data().subspan(0, rx_buffer->total_length);
  ASSERT_EQ(rx_data.size(), information.length());
  ASSERT_BYTES_EQ(rx_data.data(), information.data(), rx_data.size());
}

TEST_F(SerialPppHarness, DriverRxSingleFrameFiller) {
  PushRxSpace(0, 0);
  std::string information = "Some Ipv4";
  const std::vector<uint8_t> serial_data = {
      0x7e, 0x7e, 0x7e, 0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x21, 'S',  'o',  'm',
      'e',  ' ',  'I',  'p',  'v',  '4',  0xae, 0xdf, 0x7e, 0x7e, 0x7e, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data.data(), serial_data.size(), &actual));
  ASSERT_EQ(actual, serial_data.size());
  ASSERT_OK(Wait(kEventRxCompleted));
  auto rx_buffer = PopRx();
  ASSERT_TRUE(rx_buffer.has_value());
  ASSERT_EQ(rx_buffer->meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv4));
  auto rx_data = vmo_data().subspan(0, rx_buffer->total_length);
  ASSERT_EQ(rx_data.size(), information.length());
  ASSERT_BYTES_EQ(rx_data.data(), information.data(), rx_data.size());
}

TEST_F(SerialPppHarness, DriverRxTwoJoinedFrames) {
  PushRxSpace(0, 0);
  PushRxSpace(1, kDefaultBufferReservation);
  std::string information0 = "Some Ipv4";
  std::string information1 = "Hello\x7eworld!";
  const std::vector<uint8_t> serial_data = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x21, 'S',  'o',  'm',  'e',  ' ',  'I',  'p',
      'v',  '4',  0xae, 0xdf, 0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x21, 'H',  'e',  'l',
      'l',  'o',  0x7d, 0x5e, 'w',  'o',  'r',  'l',  'd',  '!',  0x28, 0x67, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data.data(), serial_data.size(), &actual));
  ASSERT_EQ(actual, serial_data.size());

  auto validate_rx = [this](const rx_buffer_t& result, const std::string& expect) {
    ASSERT_EQ(result.meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv4),
              "buffer %d", result.id);
    auto data = vmo_data().subspan(result.id * kDefaultBufferReservation, result.total_length);
    ASSERT_EQ(data.size(), expect.size(), "buffer %d", result.id);
    ASSERT_BYTES_EQ(data.data(), expect.data(), data.size(), "buffer %d", result.id);
  };
  auto rx = WaitRx();
  ASSERT_TRUE(rx.is_ok(), "rx failed: %s", zx_status_get_string(rx.error()));
  ASSERT_NO_FATAL_FAILURES(validate_rx(rx.take_value(), information0));
  rx = WaitRx();
  ASSERT_TRUE(rx.is_ok(), "rx failed: %s", zx_status_get_string(rx.error()));
  ASSERT_NO_FATAL_FAILURES(validate_rx(rx.take_value(), information1));
}

TEST_F(SerialPppHarness, DriverRxEmpty) {
  PushRxSpace(0, 0);
  const std::vector<uint8_t> serial_data = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x57, 0x52, 0xf0, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data.data(), serial_data.size(), &actual));
  ASSERT_EQ(actual, serial_data.size());
  ASSERT_OK(Wait(kEventRxCompleted));
  auto rx_buffer = PopRx();
  ASSERT_TRUE(rx_buffer.has_value());
  ASSERT_EQ(rx_buffer->meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv6));
  ASSERT_EQ(rx_buffer->total_length, 0);
}

TEST_F(SerialPppHarness, DriverRxBadProtocol) {
  PushRxSpace(0, 0);
  PushRxSpace(1, kDefaultBufferReservation);
  const std::vector<uint8_t> serial_data = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x58, 0x52, 0xf0, 0x7e,
      0xff, 0x7d, 0x23, 0x7d, 0x20, 0x57, 0x52, 0xf0, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data.data(), serial_data.size(), &actual));
  ASSERT_EQ(actual, serial_data.size());
  ASSERT_OK(Wait(kEventRxCompleted));
  auto rx_buffer = PopRx();
  ASSERT_TRUE(rx_buffer.has_value());
  ASSERT_EQ(rx_buffer->meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv6));
  ASSERT_EQ(rx_buffer->total_length, 0);
}

TEST_F(SerialPppHarness, DriverRxBadHeader) {
  PushRxSpace(0, 0);
  PushRxSpace(1, kDefaultBufferReservation);
  const std::vector<uint8_t> serial_data = {
      0x7e, 0x7d, 0x20, 0x7d, 0x20, 0x7d, 0x20, 0x57, 0x52, 0xf0,
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x57, 0x52, 0xf0, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data.data(), serial_data.size(), &actual));
  ASSERT_EQ(actual, serial_data.size());
  ASSERT_OK(Wait(kEventRxCompleted));
  auto rx_buffer = PopRx();
  ASSERT_TRUE(rx_buffer.has_value());
  ASSERT_EQ(rx_buffer->meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv6));
  ASSERT_EQ(rx_buffer->total_length, 0);
}

TEST_F(SerialPppHarness, DriverRxTooShort) {
  PushRxSpace(0, 0);
  PushRxSpace(1, kDefaultBufferReservation);
  const std::vector<uint8_t> serial_data = {
      0x7e, 0x7d, 0x20, 0x7d, 0x20, 0x57, 0x52, 0xf0, 0x7e,
      0xff, 0x7d, 0x23, 0x7d, 0x20, 0x57, 0x52, 0xf0, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data.data(), serial_data.size(), &actual));
  ASSERT_EQ(actual, serial_data.size());
  ASSERT_OK(Wait(kEventRxCompleted));
  auto rx_buffer = PopRx();
  ASSERT_TRUE(rx_buffer.has_value());
  ASSERT_EQ(rx_buffer->meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv6));
  ASSERT_EQ(rx_buffer->total_length, 0);
}

TEST_F(SerialPppHarness, DriverRxTooLong) {
  PushRxSpace(0, 0);
  PushRxSpace(1, kDefaultBufferReservation);
  const std::vector<uint8_t> serial_data_1(1500 * 2 + 9);
  const std::vector<uint8_t> serial_data_2 = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x57, 0x52, 0xf0, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data_1.data(), serial_data_1.size(), &actual));
  ASSERT_EQ(actual, serial_data_1.size());

  actual = 0;
  ASSERT_OK(Socket().write(0, serial_data_2.data(), serial_data_2.size(), &actual));
  ASSERT_EQ(actual, serial_data_2.size());

  ASSERT_OK(Wait(kEventRxCompleted));
  auto rx_buffer = PopRx();
  ASSERT_TRUE(rx_buffer.has_value());
  ASSERT_EQ(rx_buffer->meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv6));
  ASSERT_EQ(rx_buffer->total_length, 0);
}

TEST_F(SerialPppHarness, DriverRxBadFrameCheckSequence) {
  PushRxSpace(0, 0);
  PushRxSpace(1, kDefaultBufferReservation);
  const std::vector<uint8_t> serial_data = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x57, 0x7d, 0x20, 0x7d, 0x20,
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x57, 0x52, 0xf0, 0x7e,
  };
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data.data(), serial_data.size(), &actual));
  ASSERT_EQ(actual, serial_data.size());

  ASSERT_OK(Wait(kEventRxCompleted));
  auto rx_buffer = PopRx();
  ASSERT_TRUE(rx_buffer.has_value());
  ASSERT_EQ(rx_buffer->meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv6));
  ASSERT_EQ(rx_buffer->total_length, 0);
}

TEST_F(SerialPppHarness, DriverRxTimeout) {
  Device().set_enable_rx_timeout(true);
  PushRxSpace(0, 0);
  std::string expect = "Hello\x7eworld!";
  const std::vector<uint8_t> serial_data0 = {
      0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x21, 'S',  'o',
      'm',  'e',  ' ',  'I',  'p',  'v',  '4',  0xae, 0xdf,
  };
  const std::vector<uint8_t> serial_data1 = {0x7e, 0xff, 0x7d, 0x23, 0x7d, 0x20, 0x21, 'H',
                                             'e',  'l',  'l',  'o',  0x7d, 0x5e, 'w',  'o',
                                             'r',  'l',  'd',  '!',  0x28, 0x67, 0x7e};
  size_t actual = 0;
  ASSERT_OK(Socket().write(0, serial_data0.data(), serial_data0.size(), &actual));
  ASSERT_EQ(actual, serial_data0.size());
  // Give the device plenty of time to timeout the first buffer.
  zx::nanosleep(zx::deadline_after(ppp::SerialPpp::kSerialTimeout * 10));

  ASSERT_OK(Socket().write(0, serial_data1.data(), serial_data1.size(), &actual));
  ASSERT_EQ(actual, serial_data1.size());

  // Only the second frame must have been received.
  ASSERT_OK(Wait(kEventRxCompleted));
  auto rx_buffer = PopRx();
  ASSERT_TRUE(rx_buffer.has_value());
  ASSERT_EQ(rx_buffer->meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv4));
  auto data = vmo_data().subspan(0, rx_buffer->total_length);
  ASSERT_EQ(data.size(), expect.size());
  ASSERT_BYTES_EQ(data.data(), expect.data(), data.size());
}

TEST_F(SerialPppHarness, CycleTraffic) {
  for (uint16_t i = 0; i < ppp::SerialPpp::kFifoDepth; i++) {
    PushRxSpace(i, i * kDefaultBufferReservation);
  }
  constexpr size_t kTotalFrames = ppp::SerialPpp::kFifoDepth * 16;

  // Counts the number of rx and tx observed at driver level.
  size_t rx_driver_count = 0;
  size_t tx_driver_count = 0;
  size_t tx_returned_driver_count = 0;

  // Counts the number of rx and tx observed at serial socket.
  size_t rx_serial_count = 0;
  size_t tx_serial_count = 0;

  cpp17::optional<std::pair<std::vector<uint8_t>, size_t>> pending_write;
  std::array<uint8_t, kDefaultBufferReservation> socket_read_buffer;
  auto socket_read_offset = socket_read_buffer.begin();

  auto make_span = [](size_t* counter) -> fbl::Span<uint8_t> {
    return fbl::Span(reinterpret_cast<uint8_t*>(counter), sizeof(size_t));
  };

  auto hex_buffer = [](const fbl::Span<uint8_t>& span) -> std::string {
    std::stringstream ss;
    for (auto b : span) {
      ss << std::setw(2) << std::hex << static_cast<int>(b) << ",";
    }
    return ss.str();
  };

  std::vector<uint8_t> serial_expect =
      ppp::SerializeFrame(ppp::FrameView(ppp::Protocol::Ipv4, make_span(&tx_serial_count)));

  // Enqueue FIFO-depth tx frames.
  for (uint32_t i = 0; i < ppp::SerialPpp::kFifoDepth; i++) {
    uint32_t id = i + ppp::SerialPpp::kFifoDepth;
    Tx(id, id * kDefaultBufferReservation, netdev::wire::FrameType::kIpv4,
       fbl::Span(reinterpret_cast<uint8_t*>(&tx_driver_count), sizeof(tx_driver_count)));
    tx_driver_count++;
  }

  while (rx_driver_count < kTotalFrames || tx_driver_count < kTotalFrames ||
         tx_serial_count < kTotalFrames || rx_serial_count < kTotalFrames ||
         tx_returned_driver_count < kTotalFrames) {
    zx_wait_item_t wait[] = {{
                                 .handle = Socket().get(),
                                 .waitfor = ZX_SOCKET_READABLE,
                                 .pending = 0,
                             },
                             {
                                 .handle = Event().get(),
                                 .waitfor = kEventRxCompleted | kEventTxCompleted,
                                 .pending = 0,
                             }};
    if (rx_serial_count < kTotalFrames || pending_write.has_value()) {
      wait[0].waitfor |= ZX_SOCKET_WRITABLE;
    }
    ASSERT_OK(zx_object_wait_many(wait, countof(wait), zx::time::infinite().get()));
    if (wait[0].pending & wait[0].waitfor & ZX_SOCKET_WRITABLE) {
      std::vector<uint8_t> frame;
      size_t offset;
      if (pending_write.has_value()) {
        frame = std::move(pending_write->first);
        offset = pending_write->second;
        pending_write.reset();
      } else {
        frame =
            ppp::SerializeFrame(ppp::FrameView(ppp::Protocol::Ipv4, make_span(&rx_serial_count)));
        rx_serial_count++;
        offset = 0;
      }
      size_t actual;
      ASSERT_OK(Socket().write(0, &frame[offset], frame.size() - offset, &actual));

      if (actual != frame.size() - offset) {
        pending_write = std::make_pair(std::move(frame), offset + actual);
      }
    }
    if (wait[0].pending & ZX_SOCKET_READABLE) {
      size_t actual;
      ASSERT_OK(Socket().read(0, socket_read_offset, socket_read_buffer.end() - socket_read_offset,
                              &actual));
      socket_read_offset += actual;

      while (static_cast<size_t>(socket_read_offset - socket_read_buffer.begin()) >=
             serial_expect.size()) {
        fbl::Span<uint8_t> serial_frame(socket_read_buffer.data(), serial_expect.size());

        auto maybe_frame = ppp::DeserializeFrame(serial_frame);
        ASSERT_TRUE(maybe_frame.is_ok(), "failed to deserialize: %d, buffer=[%s], expect=[%s]",
                    maybe_frame.error(), hex_buffer(serial_frame).c_str(),
                    hex_buffer(fbl::Span(serial_expect.data(), serial_expect.size())).c_str());
        auto& frame = maybe_frame.value();
        ASSERT_EQ(frame.protocol, ppp::Protocol::Ipv4);
        ASSERT_EQ(frame.information.size(), sizeof(tx_serial_count));
        ASSERT_BYTES_EQ(frame.information.data(), reinterpret_cast<uint8_t*>(&tx_serial_count),
                        sizeof(tx_serial_count));
        socket_read_offset = std::copy(socket_read_buffer.begin() + serial_frame.size(),
                                       socket_read_offset, socket_read_buffer.begin());
        // Update serial expectation.
        tx_serial_count++;
        serial_expect =
            ppp::SerializeFrame(ppp::FrameView(ppp::Protocol::Ipv4, make_span(&tx_serial_count)));
      }
    }
    if (wait[1].pending & kEventRxCompleted) {
      auto received = PopAllRxAndClearEvent();
      while (!received.empty()) {
        rx_buffer_t buffer = received.front();
        received.pop();
        ASSERT_EQ(buffer.id, rx_driver_count % ppp::SerialPpp::kFifoDepth);
        uint64_t offset = buffer.id * kDefaultBufferReservation;
        ASSERT_EQ(buffer.meta.frame_type, static_cast<uint8_t>(netdev::wire::FrameType::kIpv4));
        ASSERT_EQ(buffer.total_length, sizeof(rx_driver_count));
        ASSERT_BYTES_EQ(vmo_data().begin() + offset, reinterpret_cast<uint8_t*>(&rx_driver_count),
                        sizeof(rx_driver_count));
        rx_driver_count++;
        PushRxSpace(buffer.id, offset);
      }
    }
    if (wait[1].pending & kEventTxCompleted) {
      auto tx_completed = PopAllTxAndClearEvent();
      while (!tx_completed.empty()) {
        tx_result_t result = tx_completed.front();
        tx_completed.pop();
        ASSERT_OK(result.status);
        ASSERT_EQ(result.id, (tx_returned_driver_count % ppp::SerialPpp::kFifoDepth) +
                                 ppp::SerialPpp::kFifoDepth);
        tx_returned_driver_count++;
        if (tx_driver_count < kTotalFrames) {
          Tx(result.id, result.id * kDefaultBufferReservation, netdev::wire::FrameType::kIpv4,
             make_span(&tx_driver_count));
          tx_driver_count++;
        }
      }
    }
  }
  EXPECT_EQ(tx_driver_count, kTotalFrames);
  EXPECT_EQ(rx_driver_count, kTotalFrames);
  EXPECT_EQ(rx_serial_count, kTotalFrames);
  EXPECT_EQ(tx_serial_count, kTotalFrames);
  EXPECT_EQ(tx_returned_driver_count, kTotalFrames);
}

TEST_F(SerialPppHarness, TestStatus) {
  // NB: Device is brought online on startup by the harness so we should see that event from the get
  // go.
  bool online = true;
  for (int i = 0; i < 5; i++) {
    ASSERT_OK(Wait(kEventStatusChanged));
    auto status = TakeStatus();
    ASSERT_TRUE(status.has_value());
    status_t read;
    Device().NetworkDeviceImplGetStatus(&read);
    if (online) {
      ASSERT_EQ(status->flags, static_cast<uint32_t>(netdev::wire::StatusFlags::kOnline));
      ASSERT_EQ(read.flags, static_cast<uint32_t>(netdev::wire::StatusFlags::kOnline));
      Device().NetworkDeviceImplStop([](void* cookie) {}, nullptr);
    } else {
      ASSERT_EQ(status->flags, 0);
      ASSERT_EQ(read.flags, 0);
      Device().NetworkDeviceImplStart([](void* cookie) {}, nullptr);
    }
    online = !online;
  }
}

}  // namespace
