#include <gtest/gtest.h>
#include "../../src/libs/CircularBuffer.h"

// Test fixture for CircularBuffer
class CircularBufferTest : public ::testing::Test {
protected:
    void SetUp() override {
        // Initialization code that runs before each test
        buffer = new CircularBuffer<int>(5); // Create a circular buffer of integers with capacity 5
    }

    void TearDown() override {
        // Clean-up code that runs after each test
        delete buffer;
    }

    // Member variables accessible in test cases
    CircularBuffer<int>* buffer;
};

// Test CircularBuffer push and pop operations
TEST_F(CircularBufferTest, PushAndPop) {
    // Push some integers into the circular buffer
    EXPECT_EQ(buffer->pushBack(10), ErrorCode::SUCCESS);
    EXPECT_EQ(buffer->pushBack(20), ErrorCode::SUCCESS);
    EXPECT_EQ(buffer->pushBack(30), ErrorCode::SUCCESS);

    // Pop integers from the circular buffer and check values
    int item;
    EXPECT_EQ(buffer->popFront(item), ErrorCode::SUCCESS);
    EXPECT_EQ(item, 10);
    EXPECT_EQ(buffer->popFront(item), ErrorCode::SUCCESS);
    EXPECT_EQ(item, 20);
    EXPECT_EQ(buffer->popFront(item), ErrorCode::SUCCESS);
    EXPECT_EQ(item, 30);
}

// Test CircularBuffer with different types
TEST_F(CircularBufferTest, DifferentTypes) {
    // Create a circular buffer of characters with capacity 3
    CircularBuffer<char> charBuffer(3);

    // Push some characters into the circular buffer
    EXPECT_EQ(charBuffer.pushBack('a'), ErrorCode::SUCCESS);
    EXPECT_EQ(charBuffer.pushBack('b'), ErrorCode::SUCCESS);
    EXPECT_EQ(charBuffer.pushBack('c'), ErrorCode::SUCCESS);

    // Pop characters from the circular buffer and check values
    char c;
    EXPECT_EQ(charBuffer.popFront(c), ErrorCode::SUCCESS);
    EXPECT_EQ(c, 'a');
    EXPECT_EQ(charBuffer.popFront(c), ErrorCode::SUCCESS);
    EXPECT_EQ(c, 'b');
    EXPECT_EQ(charBuffer.popFront(c), ErrorCode::SUCCESS);
    EXPECT_EQ(c, 'c');
}

// Test CircularBuffer with full and empty conditions
TEST_F(CircularBufferTest, FullAndEmpty) {
    // Fill up the buffer
    buffer->pushBack(10);
    buffer->pushBack(20);
    buffer->pushBack(30);

    // Try pushing into a full buffer
    EXPECT_EQ(buffer->pushBack(40), ErrorCode::BUFFER_FULL);

    // Pop all elements from the buffer
    int item;
    EXPECT_EQ(buffer->popFront(item), ErrorCode::SUCCESS);
    EXPECT_EQ(buffer->popFront(item), ErrorCode::SUCCESS);
    EXPECT_EQ(buffer->popFront(item), ErrorCode::SUCCESS);

    // Try popping from an empty buffer
    EXPECT_EQ(buffer->popFront(item), ErrorCode::BUFFER_EMPTY);
}