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

#include <fidl/fuchsia.device/cpp/wire.h>
#include <lib/zx/eventpair.h>
#include <lib/zx/time.h>

#include <zxtest/zxtest.h>

namespace {

bool IsReadable(const zx::eventpair& event) {
  zx_status_t status = event.wait_one(
      static_cast<zx_rights_t>(fuchsia_device::wire::DeviceSignal::kReadable), zx::time(), nullptr);
  return status == ZX_OK;
}

TEST(FifoTestCase, EmptyRead) {
  zx::eventpair fifo_event, remote;
  ASSERT_OK(zx::eventpair::create(0, &fifo_event, &remote));

  Fifo fifo(std::move(remote));

  // Should not be signaled as readable
  ASSERT_FALSE(IsReadable(fifo_event));

  uint8_t buffer[16];
  size_t actual = 100;
  ASSERT_STATUS(fifo.Read(buffer, sizeof(buffer), &actual), ZX_ERR_SHOULD_WAIT);
  ASSERT_EQ(actual, 0);
}

TEST(FifoTestCase, SomeData) {
  zx::eventpair fifo_event, remote;
  ASSERT_OK(zx::eventpair::create(0, &fifo_event, &remote));

  Fifo fifo(std::move(remote));
  uint8_t buffer[16] = {};
  for (size_t i = 0; i < sizeof(buffer); ++i) {
    buffer[i] = static_cast<uint8_t>(i + 1);
  }
  size_t actual = 100;
  ASSERT_STATUS(fifo.Write(buffer, sizeof(buffer), &actual), ZX_OK);
  ASSERT_EQ(actual, sizeof(buffer));

  // Should be readable now
  ASSERT_TRUE(IsReadable(fifo_event));

  // Read all but the last byte
  uint8_t buffer2[sizeof(buffer)] = {};
  ASSERT_STATUS(fifo.Read(buffer2, sizeof(buffer2) - 1, &actual), ZX_OK);
  ASSERT_EQ(actual, sizeof(buffer2) - 1);
  ASSERT_BYTES_EQ(buffer, buffer2, actual);

  // Should be readable still
  ASSERT_TRUE(IsReadable(fifo_event));

  // Read the last byte
  ASSERT_STATUS(fifo.Read(buffer2, sizeof(buffer2), &actual), ZX_OK);
  ASSERT_EQ(actual, 1);
  ASSERT_EQ(buffer2[0], buffer[sizeof(buffer) - 1]);

  // Should not be readable now
  ASSERT_FALSE(IsReadable(fifo_event));
}

TEST(FifoTestCase, Fill) {
  zx::eventpair fifo_event, remote;
  ASSERT_OK(zx::eventpair::create(0, &fifo_event, &remote));

  Fifo fifo(std::move(remote));

  // Do this twice to try to catch bookkeeping errors
  for (size_t j = 0; j < 2; ++j) {
    uint8_t buffer[Fifo::kFifoSize + 1] = {};
    for (size_t i = 0; i < sizeof(buffer); ++i) {
      buffer[i] = static_cast<uint8_t>(j * Fifo::kFifoSize / 2 + i + 1);
    }
    size_t actual = 100;
    ASSERT_STATUS(fifo.Write(buffer, sizeof(buffer), &actual), ZX_OK);
    // We should end up short one byte
    ASSERT_EQ(actual, Fifo::kFifoSize);

    // Should be readable now
    ASSERT_TRUE(IsReadable(fifo_event));

    // Read all back out
    uint8_t buffer2[sizeof(buffer)] = {};
    ASSERT_STATUS(fifo.Read(buffer2, sizeof(buffer2), &actual), ZX_OK);
    ASSERT_EQ(actual, Fifo::kFifoSize);
    ASSERT_BYTES_EQ(buffer, buffer2, actual);

    // Should not be readable now
    ASSERT_FALSE(IsReadable(fifo_event));
  }
}

TEST(FifoTestCase, Wrapping) {
  zx::eventpair fifo_event, remote;
  ASSERT_OK(zx::eventpair::create(0, &fifo_event, &remote));

  Fifo fifo(std::move(remote));

  uint8_t buffer[Fifo::kFifoSize] = {};
  for (size_t i = 0; i < sizeof(buffer); ++i) {
    buffer[i] = static_cast<uint8_t>(i + 1);
  }
  size_t actual = 100;
  ASSERT_STATUS(fifo.Write(buffer, sizeof(buffer), &actual), ZX_OK);
  ASSERT_EQ(actual, sizeof(buffer));

  // Read half back out
  uint8_t buffer2[sizeof(buffer) / 2] = {};
  ASSERT_STATUS(fifo.Read(buffer2, sizeof(buffer2), &actual), ZX_OK);
  ASSERT_EQ(actual, sizeof(buffer2));
  ASSERT_BYTES_EQ(buffer, buffer2, actual);

  size_t remaining = sizeof(buffer) - sizeof(buffer2);

  // Fill the fifo back up
  for (size_t i = 0; i < sizeof(buffer2); ++i) {
    buffer[i] = static_cast<uint8_t>(3 * i + 1);
  }
  ASSERT_STATUS(fifo.Write(buffer, sizeof(buffer2), &actual), ZX_OK);
  ASSERT_EQ(actual, sizeof(buffer2));

  // Read the rest back out
  uint8_t buffer3[sizeof(buffer)] = {};
  ASSERT_STATUS(fifo.Read(buffer3, sizeof(buffer3), &actual), ZX_OK);
  ASSERT_EQ(actual, sizeof(buffer3));
  ASSERT_BYTES_EQ(buffer + sizeof(buffer2), buffer3, remaining);
  ASSERT_BYTES_EQ(buffer, buffer3 + remaining, sizeof(buffer2));

  // Should not be readable now
  ASSERT_FALSE(IsReadable(fifo_event));
}

}  // namespace
