#include <private/dvr/buffer_hub_queue_producer.h>

#include <base/logging.h>
#include <gui/IProducerListener.h>
#include <gui/Surface.h>

#include <gtest/gtest.h>

namespace android {
namespace dvr {

namespace {

// Default dimensions before setDefaultBufferSize is called by the consumer.
constexpr uint32_t kDefaultWidth = 1;
constexpr uint32_t kDefaultHeight = 1;

// Default format before setDefaultBufferFormat is called by the consumer.
constexpr PixelFormat kDefaultFormat = HAL_PIXEL_FORMAT_RGBA_8888;
constexpr int kDefaultConsumerUsageBits = 0;

// Default transform hint before setTransformHint is called by the consumer.
constexpr uint32_t kDefaultTransformHint = 0;

constexpr int kTestApi = NATIVE_WINDOW_API_CPU;
constexpr int kTestApiOther = NATIVE_WINDOW_API_EGL;
constexpr int kTestApiInvalid = 0xDEADBEEF;
constexpr int kTestProducerUsageBits = 0;
constexpr bool kTestControlledByApp = true;

// Builder pattern to slightly vary *almost* correct input
// -- avoids copying and pasting
struct QueueBufferInputBuilder {
  IGraphicBufferProducer::QueueBufferInput build() {
    return IGraphicBufferProducer::QueueBufferInput(
        mTimestamp, mIsAutoTimestamp, mDataSpace, mCrop, mScalingMode,
        mTransform, mFence);
  }

  QueueBufferInputBuilder& setTimestamp(int64_t timestamp) {
    this->mTimestamp = timestamp;
    return *this;
  }

  QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) {
    this->mIsAutoTimestamp = isAutoTimestamp;
    return *this;
  }

  QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
    this->mDataSpace = dataSpace;
    return *this;
  }

  QueueBufferInputBuilder& setCrop(Rect crop) {
    this->mCrop = crop;
    return *this;
  }

  QueueBufferInputBuilder& setScalingMode(int scalingMode) {
    this->mScalingMode = scalingMode;
    return *this;
  }

  QueueBufferInputBuilder& setTransform(uint32_t transform) {
    this->mTransform = transform;
    return *this;
  }

  QueueBufferInputBuilder& setFence(sp<Fence> fence) {
    this->mFence = fence;
    return *this;
  }

 private:
  int64_t mTimestamp{1384888611};
  bool mIsAutoTimestamp{false};
  android_dataspace mDataSpace{HAL_DATASPACE_UNKNOWN};
  Rect mCrop{Rect(kDefaultWidth, kDefaultHeight)};
  int mScalingMode{0};
  uint32_t mTransform{0};
  sp<Fence> mFence{Fence::NO_FENCE};
};

// This is a test that covers our implementation of bufferhubqueue-based
// IGraphicBufferProducer.
class BufferHubQueueProducerTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    const ::testing::TestInfo* const testInfo =
        ::testing::UnitTest::GetInstance()->current_test_info();
    ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(),
             testInfo->name());

    mProducer = BufferHubQueueProducer::Create();
    ASSERT_TRUE(mProducer != nullptr);
    mSurface = new Surface(mProducer, true);
    ASSERT_TRUE(mSurface != nullptr);
  }

  // Connect to a producer in a 'correct' fashion.
  void ConnectProducer() {
    IGraphicBufferProducer::QueueBufferOutput output;
    // Can connect the first time.
    ASSERT_EQ(NO_ERROR, mProducer->connect(kDummyListener, kTestApi,
                                           kTestControlledByApp, &output));
  }

  // Dequeue a buffer in a 'correct' fashion.
  //   Precondition: Producer is connected.
  void DequeueBuffer(int* outSlot) {
    sp<Fence> fence;
    ASSERT_NO_FATAL_FAILURE(DequeueBuffer(outSlot, &fence));
  }

  void DequeueBuffer(int* outSlot, sp<Fence>* outFence) {
    ASSERT_NE(nullptr, outSlot);
    ASSERT_NE(nullptr, outFence);

    int ret = mProducer->dequeueBuffer(outSlot, outFence, kDefaultWidth,
                                       kDefaultHeight, kDefaultFormat,
                                       kTestProducerUsageBits, nullptr);
    // BUFFER_NEEDS_REALLOCATION can be either on or off.
    ASSERT_EQ(0, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & ret);

    // Slot number should be in boundary.
    ASSERT_LE(0, *outSlot);
    ASSERT_GT(BufferQueueDefs::NUM_BUFFER_SLOTS, *outSlot);
  }

  // Create a generic "valid" input for queueBuffer
  // -- uses the default buffer format, width, etc.
  static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() {
    return QueueBufferInputBuilder().build();
  }

  const sp<IProducerListener> kDummyListener{new DummyProducerListener};

  sp<BufferHubQueueProducer> mProducer;
  sp<Surface> mSurface;
};

TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) {
  IGraphicBufferProducer::QueueBufferOutput output;

  // NULL output returns BAD_VALUE
  EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi,
                                          kTestControlledByApp, nullptr));

  // Invalid API returns bad value
  EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApiInvalid,
                                          kTestControlledByApp, &output));
}

TEST_F(BufferHubQueueProducerTest, ConnectAgain_ReturnsError) {
  ASSERT_NO_FATAL_FAILURE(ConnectProducer());

  // Can't connect when there is already a producer connected.
  IGraphicBufferProducer::QueueBufferOutput output;
  EXPECT_EQ(BAD_VALUE, mProducer->connect(kDummyListener, kTestApi,
                                          kTestControlledByApp, &output));
}

TEST_F(BufferHubQueueProducerTest, Disconnect_Succeeds) {
  ASSERT_NO_FATAL_FAILURE(ConnectProducer());

  ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
}

TEST_F(BufferHubQueueProducerTest, Disconnect_ReturnsError) {
  ASSERT_NO_FATAL_FAILURE(ConnectProducer());

  // Must disconnect with same API number
  EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiOther));
  // API must not be out of range
  EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiInvalid));
}

TEST_F(BufferHubQueueProducerTest, Query_Succeeds) {
  ASSERT_NO_FATAL_FAILURE(ConnectProducer());

  int32_t value = -1;
  EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_WIDTH, &value));
  EXPECT_EQ(kDefaultWidth, static_cast<uint32_t>(value));

  EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
  EXPECT_EQ(kDefaultHeight, static_cast<uint32_t>(value));

  EXPECT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_FORMAT, &value));
  EXPECT_EQ(kDefaultFormat, value);

  EXPECT_EQ(NO_ERROR,
            mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value));
  EXPECT_LE(0, value);
  EXPECT_GE(BufferQueueDefs::NUM_BUFFER_SLOTS, static_cast<size_t>(value));

  EXPECT_EQ(NO_ERROR,
            mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value));
  EXPECT_FALSE(value);  // Can't run behind when we haven't touched the queue

  EXPECT_EQ(NO_ERROR,
            mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value));
  EXPECT_EQ(kDefaultConsumerUsageBits, value);
}

TEST_F(BufferHubQueueProducerTest, Query_ReturnsError) {
  ASSERT_NO_FATAL_FAILURE(ConnectProducer());

  // One past the end of the last 'query' enum value. Update this if we add more
  // enums.
  const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1;

  int value;
  // What was out of range
  EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ -1, &value));
  EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ 0xDEADBEEF, &value));
  EXPECT_EQ(BAD_VALUE,
            mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value));

  // Some enums from window.h are 'invalid'
  EXPECT_EQ(BAD_VALUE,
            mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value));
  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value));
  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value));
  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value));
  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value));

  // Value was NULL
  EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/ NULL));
}

TEST_F(BufferHubQueueProducerTest, Queue_Succeeds) {
  int slot = -1;

  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));

  // Request the buffer (pre-requisite for queueing)
  sp<GraphicBuffer> buffer;
  ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));

  // A generic "valid" input
  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
  IGraphicBufferProducer::QueueBufferOutput output;

  // Queue the buffer back into the BQ
  ASSERT_EQ(NO_ERROR, mProducer->queueBuffer(slot, input, &output));

  EXPECT_EQ(kDefaultWidth, output.width);
  EXPECT_EQ(kDefaultHeight, output.height);
  EXPECT_EQ(kDefaultTransformHint, output.transformHint);

  // BufferHubQueue delivers buffers to consumer immediately.
  EXPECT_EQ(0u, output.numPendingBuffers);

  // Note that BufferHubQueue doesn't support nextFrameNumber as it seems to
  // be a SurfaceFlinger specific optimization.
  EXPECT_EQ(0u, output.nextFrameNumber);

  // Buffer was not in the dequeued state
  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
}

// Test invalid slot number
TEST_F(BufferHubQueueProducerTest, QueueInvalidSlot_ReturnsError) {
  ASSERT_NO_FATAL_FAILURE(ConnectProducer());

  // A generic "valid" input
  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
  IGraphicBufferProducer::QueueBufferOutput output;

  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ -1, input, &output));
  EXPECT_EQ(BAD_VALUE,
            mProducer->queueBuffer(/*slot*/ 0xDEADBEEF, input, &output));
  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueueDefs::NUM_BUFFER_SLOTS,
                                              input, &output));
}

// Slot was not in the dequeued state (all slots start out in Free state)
TEST_F(BufferHubQueueProducerTest, QueueNotDequeued_ReturnsError) {
  ASSERT_NO_FATAL_FAILURE(ConnectProducer());

  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
  IGraphicBufferProducer::QueueBufferOutput output;

  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ 0, input, &output));
}

// Slot was enqueued without requesting a buffer
TEST_F(BufferHubQueueProducerTest, QueueNotRequested_ReturnsError) {
  int slot = -1;

  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));

  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
  IGraphicBufferProducer::QueueBufferOutput output;

  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
}

// Test when fence was NULL
TEST_F(BufferHubQueueProducerTest, QueueNoFence_ReturnsError) {
  int slot = -1;

  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));

  sp<GraphicBuffer> buffer;
  ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));

  sp<Fence> nullFence = NULL;

  IGraphicBufferProducer::QueueBufferInput input =
      QueueBufferInputBuilder().setFence(nullFence).build();
  IGraphicBufferProducer::QueueBufferOutput output;

  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
}

// Test scaling mode was invalid
TEST_F(BufferHubQueueProducerTest, QueueTestInvalidScalingMode_ReturnsError) {
  int slot = -1;

  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));

  sp<GraphicBuffer> buffer;
  ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));

  IGraphicBufferProducer::QueueBufferInput input =
      QueueBufferInputBuilder().setScalingMode(-1).build();
  IGraphicBufferProducer::QueueBufferOutput output;

  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));

  input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build();

  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
}

// Test crop rect is out of bounds of the buffer dimensions
TEST_F(BufferHubQueueProducerTest, QueueCropOutOfBounds_ReturnsError) {
  int slot = -1;

  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));

  sp<GraphicBuffer> buffer;
  ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));

  IGraphicBufferProducer::QueueBufferInput input =
      QueueBufferInputBuilder()
          .setCrop(Rect(kDefaultWidth + 1, kDefaultHeight + 1))
          .build();
  IGraphicBufferProducer::QueueBufferOutput output;

  EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output));
}

TEST_F(BufferHubQueueProducerTest, CancelBuffer_Succeeds) {
  int slot = -1;
  sp<Fence> fence;

  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));

  // Should be able to cancel buffer after a dequeue.
  EXPECT_EQ(NO_ERROR, mProducer->cancelBuffer(slot, fence));
}

TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Succeeds) {
  return;
  ASSERT_NO_FATAL_FAILURE(ConnectProducer());

  int minUndequeuedBuffers;
  ASSERT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
                                       &minUndequeuedBuffers));

  const int minBuffers = 1;
  const int maxBuffers =
      BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;

  ASSERT_EQ(NO_ERROR, mProducer->setAsyncMode(false))
      << "async mode: " << false;
  ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(minBuffers))
      << "bufferCount: " << minBuffers;

  // Should now be able to dequeue up to minBuffers times
  // Should now be able to dequeue up to maxBuffers times
  int slot = -1;
  for (int i = 0; i < minBuffers; ++i) {
    ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
  }

  ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(maxBuffers));

  // queue the first buffer to enable max dequeued buffer count checking
  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
  IGraphicBufferProducer::QueueBufferOutput output;
  sp<GraphicBuffer> buffer;
  ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));
  ASSERT_EQ(NO_ERROR, mProducer->queueBuffer(slot, input, &output));

  sp<Fence> fence;
  for (int i = 0; i < maxBuffers; ++i) {
    ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence));
  }

  // Cancel a buffer, so we can decrease the buffer count
  ASSERT_EQ(NO_ERROR, mProducer->cancelBuffer(slot, fence));

  // Should now be able to decrease the max dequeued count by 1
  ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(maxBuffers - 1));
}

TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) {
  ASSERT_NO_FATAL_FAILURE(ConnectProducer());

  int minUndequeuedBuffers;
  ASSERT_EQ(NO_ERROR, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
                                       &minUndequeuedBuffers));

  const int minBuffers = 1;
  const int maxBuffers =
      BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers;

  ASSERT_EQ(NO_ERROR, mProducer->setAsyncMode(false))
      << "async mode: " << false;
  // Buffer count was out of range
  EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0))
      << "bufferCount: " << 0;
  EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1))
      << "bufferCount: " << maxBuffers + 1;

  // Set max dequeue count to 2
  ASSERT_EQ(NO_ERROR, mProducer->setMaxDequeuedBufferCount(2));
  // Dequeue 2 buffers
  int slot = -1;
  sp<Fence> fence;
  for (int i = 0; i < 2; i++) {
    ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION &
                      (mProducer->dequeueBuffer(
                          &slot, &fence, kDefaultWidth, kDefaultHeight,
                          kDefaultFormat, kTestProducerUsageBits, nullptr)))
        << "slot: " << slot;
  }

  // Client has too many buffers dequeued
  EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1))
      << "bufferCount: " << minBuffers;
}

TEST_F(BufferHubQueueProducerTest,
       DisconnectedProducerReturnsError_dequeueBuffer) {
  int slot = -1;
  sp<Fence> fence;

  ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth,
                                              kDefaultHeight, kDefaultFormat,
                                              kTestProducerUsageBits, nullptr));
}

TEST_F(BufferHubQueueProducerTest,
       DisconnectedProducerReturnsError_requestBuffer) {
  int slot = -1;
  sp<GraphicBuffer> buffer;

  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));

  // Shouldn't be able to request buffer after disconnect.
  ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
  ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer));
}

TEST_F(BufferHubQueueProducerTest,
       DisconnectedProducerReturnsError_queueBuffer) {
  int slot = -1;
  sp<GraphicBuffer> buffer;

  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
  ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));

  // A generic "valid" input
  IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput();
  IGraphicBufferProducer::QueueBufferOutput output;

  // Shouldn't be able to queue buffer after disconnect.
  ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
  ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output));
}

TEST_F(BufferHubQueueProducerTest,
       DisconnectedProducerReturnsError_cancelBuffer) {
  int slot = -1;
  sp<GraphicBuffer> buffer;

  ASSERT_NO_FATAL_FAILURE(ConnectProducer());
  ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot));
  ASSERT_EQ(NO_ERROR, mProducer->requestBuffer(slot, &buffer));

  // Shouldn't be able to cancel buffer after disconnect.
  ASSERT_EQ(NO_ERROR, mProducer->disconnect(kTestApi));
  ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, Fence::NO_FENCE));
}

}  // namespace

}  // namespace dvr
}  // namespace android
