#include <dvr/dvr_api.h>
#include <dvr/dvr_buffer_queue.h>
#include <gui/Surface.h>
#include <private/dvr/buffer_hub_queue_client.h>

#include <base/logging.h>
#include <gtest/gtest.h>

#include "../dvr_internal.h"
#include "../dvr_buffer_queue_internal.h"

namespace android {
namespace dvr {

namespace {

static constexpr uint32_t kBufferWidth = 100;
static constexpr uint32_t kBufferHeight = 1;
static constexpr uint32_t kLayerCount = 1;
static constexpr uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
static constexpr uint64_t kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY;
static constexpr size_t kQueueCapacity = 3;

typedef uint64_t TestMeta;

class DvrBufferQueueTest : public ::testing::Test {
 public:
  static void BufferAvailableCallback(void* context) {
    DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
    thiz->HandleBufferAvailable();
  }

  static void BufferRemovedCallback(DvrReadBuffer* buffer, void* context) {
    DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context);
    thiz->HandleBufferRemoved(buffer);
  }

 protected:
  void SetUp() override {
    config_builder_ = ProducerQueueConfigBuilder()
                          .SetDefaultWidth(kBufferWidth)
                          .SetDefaultHeight(kBufferHeight)
                          .SetDefaultFormat(kBufferFormat)
                          .SetMetadata<TestMeta>();
  }

  void TearDown() override {
    if (write_queue_ != nullptr) {
      dvrWriteBufferQueueDestroy(write_queue_);
      write_queue_ = nullptr;
    }
  }

  void CreateWriteBufferQueue() {
    write_queue_ = new DvrWriteBufferQueue(
        ProducerQueue::Create(config_builder_.Build(), UsagePolicy{}));
    ASSERT_NE(nullptr, write_queue_);
  }

  void AllocateBuffers(size_t buffer_count) {
    auto status = write_queue_->producer_queue()->AllocateBuffers(
        kBufferWidth, kBufferHeight, kLayerCount, kBufferFormat, kBufferUsage,
        buffer_count);
    ASSERT_TRUE(status.ok());
  }

  void HandleBufferAvailable() {
    buffer_available_count_ += 1;
    ALOGD_IF(TRACE, "Buffer avaiable, count=%d", buffer_available_count_);
  }

  void HandleBufferRemoved(DvrReadBuffer* buffer) {
    buffer_removed_count_ += 1;
    ALOGD_IF(TRACE, "Buffer removed, buffer=%p, count=%d", buffer,
             buffer_removed_count_);
  }

  ProducerQueueConfigBuilder config_builder_;
  DvrWriteBufferQueue* write_queue_{nullptr};
  int buffer_available_count_{0};
  int buffer_removed_count_{0};
};

TEST_F(DvrBufferQueueTest, TestWrite_QueueCreateDestroy) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());

  dvrWriteBufferQueueDestroy(write_queue_);
  write_queue_ = nullptr;
}

TEST_F(DvrBufferQueueTest, TestWrite_QueueGetCapacity) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity));

  size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_);

  ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
  ASSERT_EQ(kQueueCapacity, capacity);
}

TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromWriteQueue) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());

  DvrReadBufferQueue* read_queue = nullptr;
  int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);

  ASSERT_EQ(0, ret);
  ASSERT_NE(nullptr, read_queue);

  dvrReadBufferQueueDestroy(read_queue);
}

TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());

  DvrReadBufferQueue* read_queue1 = nullptr;
  DvrReadBufferQueue* read_queue2 = nullptr;
  int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);

  ASSERT_EQ(0, ret);
  ASSERT_NE(nullptr, read_queue1);

  ret = dvrReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
  ASSERT_EQ(0, ret);
  ASSERT_NE(nullptr, read_queue2);
  ASSERT_NE(read_queue1, read_queue2);

  dvrReadBufferQueueDestroy(read_queue1);
  dvrReadBufferQueueDestroy(read_queue2);
}

TEST_F(DvrBufferQueueTest, CreateEmptyBuffer) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(3));

  DvrReadBuffer* read_buffer = nullptr;
  DvrWriteBuffer* write_buffer = nullptr;

  EXPECT_FALSE(dvrReadBufferIsValid(read_buffer));
  EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer));

  dvrReadBufferCreateEmpty(&read_buffer);
  ASSERT_NE(nullptr, read_buffer);

  dvrWriteBufferCreateEmpty(&write_buffer);
  ASSERT_NE(nullptr, write_buffer);

  EXPECT_FALSE(dvrReadBufferIsValid(read_buffer));
  EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer));

  DvrReadBufferQueue* read_queue = nullptr;

  ASSERT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue));

  const int kTimeoutMs = 0;
  int fence_fd = -1;
  ASSERT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, kTimeoutMs,
                                          write_buffer, &fence_fd));
  EXPECT_EQ(-1, fence_fd);
  EXPECT_TRUE(dvrWriteBufferIsValid(write_buffer));

  ASSERT_EQ(0, dvrWriteBufferClear(write_buffer));
  EXPECT_FALSE(dvrWriteBufferIsValid(write_buffer));
}

TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity));

  static constexpr int kTimeout = 0;
  DvrReadBufferQueue* read_queue = nullptr;
  DvrReadBuffer* rb = nullptr;
  DvrWriteBuffer* wb = nullptr;
  int fence_fd = -1;

  int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);

  ASSERT_EQ(0, ret);
  ASSERT_NE(nullptr, read_queue);

  dvrReadBufferQueueSetBufferAvailableCallback(read_queue,
                                               &BufferAvailableCallback, this);

  dvrWriteBufferCreateEmpty(&wb);
  ASSERT_NE(nullptr, wb);

  dvrReadBufferCreateEmpty(&rb);
  ASSERT_NE(nullptr, rb);

  // Gain buffer for writing.
  ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb, &fence_fd);
  ASSERT_EQ(0, ret);
  ASSERT_TRUE(dvrWriteBufferIsValid(wb));
  ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
           wb, fence_fd);
  pdx::LocalHandle release_fence(fence_fd);

  // Post buffer to the read_queue.
  TestMeta seq = 42U;
  ret = dvrWriteBufferPost(wb, /* fence */ -1, &seq, sizeof(seq));
  ASSERT_EQ(0, ret);
  dvrWriteBufferDestroy(wb);
  wb = nullptr;

  // Acquire buffer for reading.
  TestMeta acquired_seq = 0U;
  ret = dvrReadBufferQueueDequeue(read_queue, kTimeout, rb, &fence_fd,
                                  &acquired_seq, sizeof(acquired_seq));
  ASSERT_EQ(0, ret);

  // Dequeue is successfully, BufferAvailableCallback should be fired once.
  ASSERT_EQ(1, buffer_available_count_);
  ASSERT_TRUE(dvrReadBufferIsValid(rb));
  ASSERT_EQ(seq, acquired_seq);
  ALOGD_IF(TRACE,
           "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb,
           fence_fd);
  pdx::LocalHandle acquire_fence(fence_fd);

  // Release buffer to the write_queue.
  ret = dvrReadBufferRelease(rb, -1);
  ASSERT_EQ(0, ret);
  dvrReadBufferDestroy(rb);
  rb = nullptr;

  // TODO(b/34387835) Currently buffer allocation has to happen after all queues
  // are initialized.
  size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);

  ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity);
  ASSERT_EQ(kQueueCapacity, capacity);

  dvrReadBufferQueueDestroy(read_queue);
}

TEST_F(DvrBufferQueueTest, TestGetExternalSurface) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());

  ANativeWindow* window = nullptr;

  // The |write_queue_| doesn't have proper metadata (must be
  // DvrNativeBufferMetadata) configured during creation.
  int ret = dvrWriteBufferQueueGetExternalSurface(write_queue_, &window);
  ASSERT_EQ(-EINVAL, ret);
  ASSERT_EQ(nullptr, window);

  // A write queue with DvrNativeBufferMetadata should work fine.
  auto config = ProducerQueueConfigBuilder()
                    .SetMetadata<DvrNativeBufferMetadata>()
                    .Build();
  std::unique_ptr<DvrWriteBufferQueue, decltype(&dvrWriteBufferQueueDestroy)>
      write_queue(
          new DvrWriteBufferQueue(ProducerQueue::Create(config, UsagePolicy{})),
          dvrWriteBufferQueueDestroy);
  ASSERT_NE(nullptr, write_queue.get());

  ret = dvrWriteBufferQueueGetExternalSurface(write_queue.get(), &window);
  ASSERT_EQ(0, ret);
  ASSERT_NE(nullptr, window);

  sp<Surface> surface = static_cast<Surface*>(window);
  ASSERT_TRUE(Surface::isValid(surface));
}

// Create buffer queue of three buffers and dequeue three buffers out of it.
// Before each dequeue operation, we resize the buffer queue and expect the
// queue always return buffer with desired dimension.
TEST_F(DvrBufferQueueTest, TestResizeBuffer) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity));

  static constexpr int kTimeout = 0;
  int fence_fd = -1;

  DvrReadBufferQueue* read_queue = nullptr;
  DvrWriteBuffer* wb1 = nullptr;
  DvrWriteBuffer* wb2 = nullptr;
  DvrWriteBuffer* wb3 = nullptr;
  AHardwareBuffer* ahb1 = nullptr;
  AHardwareBuffer* ahb2 = nullptr;
  AHardwareBuffer* ahb3 = nullptr;
  AHardwareBuffer_Desc buffer_desc;

  int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);

  ASSERT_EQ(0, ret);
  ASSERT_NE(nullptr, read_queue);

  dvrReadBufferQueueSetBufferRemovedCallback(read_queue, &BufferRemovedCallback,
                                             this);

  dvrWriteBufferCreateEmpty(&wb1);
  ASSERT_NE(nullptr, wb1);
  dvrWriteBufferCreateEmpty(&wb2);
  ASSERT_NE(nullptr, wb2);
  dvrWriteBufferCreateEmpty(&wb3);
  ASSERT_NE(nullptr, wb3);

  // Handle all pending events on the read queue.
  ret = dvrReadBufferQueueHandleEvents(read_queue);
  ASSERT_EQ(0, ret);

  size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);
  ALOGD_IF(TRACE, "TestResizeBuffer, capacity=%zu", capacity);
  ASSERT_EQ(kQueueCapacity, capacity);

  // Resize before dequeuing.
  constexpr uint32_t w1 = 10;
  ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w1, kBufferHeight);
  ASSERT_EQ(0, ret);

  // Gain first buffer for writing. All buffers will be resized.
  ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb1, &fence_fd);
  ASSERT_EQ(0, ret);
  ASSERT_TRUE(dvrWriteBufferIsValid(wb1));
  ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1);
  pdx::LocalHandle release_fence1(fence_fd);

  // Check the buffer dimension.
  ret = dvrWriteBufferGetAHardwareBuffer(wb1, &ahb1);
  ASSERT_EQ(0, ret);
  AHardwareBuffer_describe(ahb1, &buffer_desc);
  ASSERT_EQ(w1, buffer_desc.width);
  ASSERT_EQ(kBufferHeight, buffer_desc.height);
  AHardwareBuffer_release(ahb1);

  // For the first resize, all buffers are reallocated.
  int expected_buffer_removed_count = kQueueCapacity;
  ret = dvrReadBufferQueueHandleEvents(read_queue);
  ASSERT_EQ(0, ret);
  ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);

  // Resize the queue. We are testing with blob format, keep height to be 1.
  constexpr uint32_t w2 = 20;
  ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w2, kBufferHeight);
  ASSERT_EQ(0, ret);

  // The next buffer we dequeued should have new width.
  ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb2, &fence_fd);
  ASSERT_EQ(0, ret);
  ASSERT_TRUE(dvrWriteBufferIsValid(wb2));
  ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2,
           fence_fd);
  pdx::LocalHandle release_fence2(fence_fd);

  // Check the buffer dimension, should be new width
  ret = dvrWriteBufferGetAHardwareBuffer(wb2, &ahb2);
  ASSERT_EQ(0, ret);
  AHardwareBuffer_describe(ahb2, &buffer_desc);
  ASSERT_EQ(w2, buffer_desc.width);
  AHardwareBuffer_release(ahb2);

  // For the second resize, all but one buffers are reallocated.
  expected_buffer_removed_count += (kQueueCapacity - 1);
  ret = dvrReadBufferQueueHandleEvents(read_queue);
  ASSERT_EQ(0, ret);
  ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);

  // Resize the queue for the third time.
  constexpr uint32_t w3 = 30;
  ret = dvrWriteBufferQueueResizeBuffer(write_queue_, w3, kBufferHeight);
  ASSERT_EQ(0, ret);

  // The next buffer we dequeued should have new width.
  ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, wb3, &fence_fd);
  ASSERT_EQ(0, ret);
  ASSERT_TRUE(dvrWriteBufferIsValid(wb3));
  ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3,
           fence_fd);
  pdx::LocalHandle release_fence3(fence_fd);

  // Check the buffer dimension, should be new width
  ret = dvrWriteBufferGetAHardwareBuffer(wb3, &ahb3);
  ASSERT_EQ(0, ret);
  AHardwareBuffer_describe(ahb3, &buffer_desc);
  ASSERT_EQ(w3, buffer_desc.width);
  AHardwareBuffer_release(ahb3);

  // For the third resize, all but two buffers are reallocated.
  expected_buffer_removed_count += (kQueueCapacity - 2);
  ret = dvrReadBufferQueueHandleEvents(read_queue);
  ASSERT_EQ(0, ret);
  ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_);

  dvrReadBufferQueueDestroy(read_queue);
}

TEST_F(DvrBufferQueueTest, DequeueEmptyMetadata) {
  // Overrides default queue parameters: Empty metadata.
  config_builder_.SetMetadata<void>();
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(1));

  DvrReadBuffer* rb = nullptr;
  DvrWriteBuffer* wb = nullptr;
  dvrReadBufferCreateEmpty(&rb);
  dvrWriteBufferCreateEmpty(&wb);

  DvrReadBufferQueue* read_queue = nullptr;
  EXPECT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue));

  const int kTimeoutMs = 0;
  int fence_fd = -1;
  EXPECT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, 0, wb, &fence_fd));

  EXPECT_EQ(0, dvrWriteBufferPost(wb, /*fence=*/-1, nullptr, 0));
  EXPECT_EQ(0, dvrWriteBufferClear(wb));
  dvrWriteBufferDestroy(wb);
  wb = nullptr;

  // When acquire buffer, it's legit to pass nullptr as out_meta iff metadata
  // size is Zero.
  EXPECT_EQ(0, dvrReadBufferQueueDequeue(read_queue, kTimeoutMs, rb, &fence_fd,
                                         nullptr, 0));
  EXPECT_TRUE(dvrReadBufferIsValid(rb));
}

TEST_F(DvrBufferQueueTest, DequeueMismatchMetadata) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(1));

  DvrReadBuffer* rb = nullptr;
  DvrWriteBuffer* wb = nullptr;
  dvrReadBufferCreateEmpty(&rb);
  dvrWriteBufferCreateEmpty(&wb);

  DvrReadBufferQueue* read_queue = nullptr;
  EXPECT_EQ(0, dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue));

  const int kTimeoutMs = 0;
  int fence_fd = -1;
  EXPECT_EQ(0, dvrWriteBufferQueueDequeue(write_queue_, 0, wb, &fence_fd));

  TestMeta seq = 42U;
  EXPECT_EQ(0, dvrWriteBufferPost(wb, /*fence=*/-1, &seq, sizeof(seq)));
  EXPECT_EQ(0, dvrWriteBufferClear(wb));
  dvrWriteBufferDestroy(wb);
  wb = nullptr;

  // Dequeue with wrong metadata will cause EINVAL.
  int8_t wrong_metadata;
  EXPECT_EQ(-EINVAL,
            dvrReadBufferQueueDequeue(read_queue, kTimeoutMs, rb, &fence_fd,
                                      &wrong_metadata, sizeof(wrong_metadata)));
  EXPECT_FALSE(dvrReadBufferIsValid(rb));

  // Dequeue with empty metadata will cause EINVAL.
  EXPECT_EQ(-EINVAL, dvrReadBufferQueueDequeue(read_queue, kTimeoutMs, rb,
                                               &fence_fd, nullptr, 0));
  EXPECT_FALSE(dvrReadBufferIsValid(rb));
}

TEST_F(DvrBufferQueueTest, TestReadQueueEventFd) {
  ASSERT_NO_FATAL_FAILURE(CreateWriteBufferQueue());
  ASSERT_NO_FATAL_FAILURE(AllocateBuffers(kQueueCapacity));

  DvrReadBufferQueue* read_queue = nullptr;
  int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);

  ASSERT_EQ(0, ret);
  ASSERT_NE(nullptr, read_queue);

  int event_fd = dvrReadBufferQueueGetEventFd(read_queue);
  ASSERT_GT(event_fd, 0);
}

}  // namespace

}  // namespace dvr
}  // namespace android
