#include "../collections/Deque.hpp"

#include "gtest_printers.hpp"
#include <gtest/gtest.h>

class DequeTest : public testing::Test
{
protected:
	virtual void SetUp() override
	{
		testDeque.PushBack(3);
		testDeque.PushBack(5);
		testDeque.PushFront(2);
		testDeque.PushFront(1);
	}

	sprawl::collections::Deque<int> testDeque;
};

TEST_F(DequeTest, BasicSetupWorks)
{
	EXPECT_EQ(1, testDeque[0]);
	EXPECT_EQ(2, testDeque[1]);
	EXPECT_EQ(3, testDeque[2]);
	EXPECT_EQ(5, testDeque[3]);
}

TEST_F(DequeTest, FrontWorks)
{
	ASSERT_EQ(1, testDeque.Front());
}

TEST_F(DequeTest, BackWorks)
{
	ASSERT_EQ(5, testDeque.Back());
}

TEST_F(DequeTest, IterationAndInsertWorks)
{
	for(auto it = testDeque.begin(); it != testDeque.end(); ++it)
	{
		if(it.Value() == 5)
		{
			testDeque.Insert(it, 4);
			break;
		}
	}

	int value = 0;

	for(auto it = testDeque.begin(); it != testDeque.end(); ++it)
	{
		EXPECT_EQ(value + 1, it.Value());
		value = it.Value();
	}
}

TEST_F(DequeTest, PopFrontWorks)
{
	testDeque.PopFront();
	ASSERT_EQ(2, testDeque.Front());
}

TEST_F(DequeTest, PopBackWorks)
{
	testDeque.PopBack();
	ASSERT_EQ(3, testDeque.Back());
}

TEST_F(DequeTest, EraseWorks)
{

	for(auto it = testDeque.begin(); it != testDeque.end(); ++it)
	{
		if(it.Value() == 3)
		{
			testDeque.Erase(it);
			break;
		}
	}

	for(auto it = testDeque.begin(); it != testDeque.end(); ++it)
	{
		ASSERT_NE(3, it.Value());
	}
}

TEST_F(DequeTest, GrowWorks)
{
	sprawl::collections::Deque<int> deque2(sprawl::collections::Capacity(5));

	for(int i = 50; i < 75; ++i)
	{
		deque2.PushBack(i);
	}
	for(int i = 49; i > 0; --i)
	{
		deque2.PushFront(i);
	}
	for(int i = 75; i <= 100; ++i)
	{
		deque2.PushBack(i);
	}

	int value = 0;

	EXPECT_EQ(1, deque2.Front());

	for(auto& num : deque2)
	{
		EXPECT_EQ(value + 1, num);
		value = num;
	}

	ASSERT_EQ(100, deque2.Back());
}

TEST_F(DequeTest, NegativeIndexingWorks)
{
	ASSERT_EQ(testDeque[-1], testDeque.Back());
}
