/*-------------------------------------------------------------------------
 * drawElements C++ Base Library
 * -----------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Array template backed by memory pool.
 *//*--------------------------------------------------------------------*/

#include "dePoolArray.hpp"

#include <algorithm>
#include <vector>

namespace de
{

static void intArrayTest (void)
{
	MemPool				pool;
	PoolArray<int>		arr		(&pool);
	PoolArray<deUint16>	arr16	(&pool);
	int					i;

	/* Test pushBack(). */
	for (i = 0; i < 5000; i++)
	{
		/* Dummy alloc to try to break alignments. */
		pool.alloc(1);

		arr.pushBack(i);
		arr16.pushBack((deInt16)i);
	}

	DE_TEST_ASSERT(arr.size() == 5000);
	DE_TEST_ASSERT(arr16.size() == 5000);
	for (i = 0; i < 5000; i++)
	{
		DE_TEST_ASSERT(arr[i] == i);
		DE_TEST_ASSERT(arr16[i] == i);
	}

	/* Test popBack(). */
	for (i = 0; i < 1000; i++)
	{
		DE_TEST_ASSERT(arr.popBack() == (4999 - i));
		DE_TEST_ASSERT(arr16.popBack() == (4999 - i));
	}

	DE_TEST_ASSERT(arr.size() == 4000);
	DE_TEST_ASSERT(arr16.size() == 4000);
	for (i = 0; i < 4000; i++)
	{
		DE_TEST_ASSERT(arr[i] == i);
		DE_TEST_ASSERT(arr16[i] == i);
	}

	/* Test resize(). */
	arr.resize(1000);
	arr16.resize(1000);
	for (i = 1000; i < 5000; i++)
	{
		arr.pushBack(i);
		arr16.pushBack((deInt16)i);
	}

	DE_TEST_ASSERT(arr.size() == 5000);
	DE_TEST_ASSERT(arr16.size() == 5000);
	for (i = 0; i < 5000; i++)
	{
		DE_TEST_ASSERT(arr[i] == i);
		DE_TEST_ASSERT(arr16[i] == i);
	}

	/* Test set() and pushBack() with reserve(). */
	PoolArray<int> arr2(&pool);
	arr2.resize(1500);
	arr2.reserve(2000);
	for (i = 0; i < 1500; i++)
		arr2[i] = i;
	for (; i < 5000; i++)
		arr2.pushBack(i);

	DE_TEST_ASSERT(arr2.size() == 5000);
	for (i = 0; i < 5000; i++)
	{
		int val = arr2[i];
		DE_TEST_ASSERT(val == i);
	}
}

static void alignedIntArrayTest (void)
{
	MemPool					pool;
	PoolArray<int, 16>		arr		(&pool);
	PoolArray<deUint16,	8>	arr16	(&pool);
	int						i;

	/* Test pushBack(). */
	for (i = 0; i < 5000; i++)
	{
		/* Dummy alloc to try to break alignments. */
		pool.alloc(1);

		arr.pushBack(i);
		arr16.pushBack((deInt16)i);
	}

	DE_TEST_ASSERT(arr.size() == 5000);
	DE_TEST_ASSERT(arr16.size() == 5000);
	for (i = 0; i < 5000; i++)
	{
		DE_TEST_ASSERT(arr[i] == i);
		DE_TEST_ASSERT(arr16[i] == i);
	}

	/* Test popBack(). */
	for (i = 0; i < 1000; i++)
	{
		DE_TEST_ASSERT(arr.popBack() == (4999 - i));
		DE_TEST_ASSERT(arr16.popBack() == (4999 - i));
	}

	DE_TEST_ASSERT(arr.size() == 4000);
	DE_TEST_ASSERT(arr16.size() == 4000);
	for (i = 0; i < 4000; i++)
	{
		DE_TEST_ASSERT(arr[i] == i);
		DE_TEST_ASSERT(arr16[i] == i);
	}

	/* Test resize(). */
	arr.resize(1000);
	arr16.resize(1000);
	for (i = 1000; i < 5000; i++)
	{
		arr.pushBack(i);
		arr16.pushBack((deInt16)i);
	}

	DE_TEST_ASSERT(arr.size() == 5000);
	DE_TEST_ASSERT(arr16.size() == 5000);
	for (i = 0; i < 5000; i++)
	{
		DE_TEST_ASSERT(arr[i] == i);
		DE_TEST_ASSERT(arr16[i] == i);
	}

	arr.resize(0);
	arr.resize(100, -123);
	DE_TEST_ASSERT(arr.size() == 100);
	for (i = 0; i < 100; i++)
		DE_TEST_ASSERT(arr[i] == -123);

	/* Test set() and pushBack() with reserve(). */
	PoolArray<int, 32> arr2(&pool);
	arr2.resize(1500);
	arr2.reserve(2000);
	for (i = 0; i < 1500; i++)
		arr2[i] = i;
	for (; i < 5000; i++)
		arr2.pushBack(i);

	DE_TEST_ASSERT(arr2.size() == 5000);
	for (i = 0; i < 5000; i++)
	{
		int val = arr2[i];
		DE_TEST_ASSERT(val == i);
	}
}

namespace
{

class RefCount
{
public:
	RefCount (void)
		: m_count(DE_NULL)
	{
	}

	RefCount (int* count)
		: m_count(count)
	{
		*m_count += 1;
	}

	RefCount (const RefCount& other)
		: m_count(other.m_count)
	{
		if (m_count)
			*m_count += 1;
	}

	~RefCount (void)
	{
		if (m_count)
			*m_count -= 1;
	}

	RefCount& operator= (const RefCount& other)
	{
		if (this == &other)
			return *this;

		if (m_count)
			*m_count -= 1;

		m_count = other.m_count;

		if (m_count)
			*m_count += 1;

		return *this;
	}

private:
	int* m_count;
};

} // anonymous

static void sideEffectTest (void)
{
	MemPool				pool;
	PoolArray<RefCount>	arr		(&pool);
	int					count	= 0;
	RefCount			counter	(&count);

	DE_TEST_ASSERT(count == 1);

	for (int i = 0; i < 127; i++)
		arr.pushBack(counter);

	DE_TEST_ASSERT(count == 128);

	for (int i = 0; i < 10; i++)
		arr.popBack();

	DE_TEST_ASSERT(count == 118);

	arr.resize(150);
	DE_TEST_ASSERT(count == 118);

	arr.resize(18);
	DE_TEST_ASSERT(count == 19);

	arr.resize(19);
	DE_TEST_ASSERT(count == 19);

	arr.clear();
	DE_TEST_ASSERT(count == 1);
}

static void iteratorTest (void)
{
	MemPool			pool;
	PoolArray<int>	arr		(&pool);

	for (int ndx = 0; ndx < 128; ndx++)
		arr.pushBack(ndx);

	// ConstIterator
	{
		const PoolArray<int>& cRef = arr;
		int ndx = 0;
		for (PoolArray<int>::ConstIterator iter = cRef.begin(); iter != cRef.end(); iter++, ndx++)
		{
			DE_TEST_ASSERT(*iter == ndx);
		}

		// Cast & interop with non-const array.
		ndx = 0;
		for (PoolArray<int>::ConstIterator iter = arr.begin(); iter != arr.end(); iter++, ndx++)
		{
			DE_TEST_ASSERT(*iter == ndx);
		}
	}

	// Arithmetics.
	DE_TEST_ASSERT(arr.end()-arr.begin() == 128);
	DE_TEST_ASSERT(*(arr.begin()+3) == 3);
	DE_TEST_ASSERT(arr.begin()[4] == 4);

	// Relational
	DE_TEST_ASSERT(arr.begin() != arr.begin()+1);
	DE_TEST_ASSERT(arr.begin() == arr.begin());
	DE_TEST_ASSERT(arr.begin() != arr.end());
	DE_TEST_ASSERT(arr.begin() < arr.end());
	DE_TEST_ASSERT(arr.begin() < arr.begin()+1);
	DE_TEST_ASSERT(arr.begin() <= arr.begin());
	DE_TEST_ASSERT(arr.end() > arr.begin());
	DE_TEST_ASSERT(arr.begin() >= arr.begin());

	// Compatibility with stl.
	DE_TEST_ASSERT(std::distance(arr.begin(), arr.end()) == 128);

	std::vector<int> vecCopy(arr.size());
	std::copy(arr.begin(), arr.end(), vecCopy.begin());
	for (int ndx = 0; ndx < (int)vecCopy.size(); ndx++)
		DE_TEST_ASSERT(vecCopy[ndx] == ndx);

	std::fill(arr.begin(), arr.end(), -1);
	for (int ndx = 0; ndx < (int)arr.size(); ndx++)
		DE_TEST_ASSERT(arr[ndx] == -1);

	std::copy(vecCopy.begin(), vecCopy.end(), arr.begin());
	for (int ndx = 0; ndx < (int)arr.size(); ndx++)
		DE_TEST_ASSERT(arr[ndx] == ndx);

	// Iterator
	{
		int ndx = 0;
		for (PoolArray<int>::Iterator iter = arr.begin(); iter != arr.end(); iter++, ndx++)
		{
			DE_TEST_ASSERT(*iter == ndx);
			if (ndx == 4)
				*iter = 0;
			else if (ndx == 7)
				*(iter-1) = 1;
		}
	}

	DE_TEST_ASSERT(arr[4] == 0);
	DE_TEST_ASSERT(arr[6] == 1);
}

void PoolArray_selfTest (void)
{
	intArrayTest();
	alignedIntArrayTest();
	sideEffectTest();
	iteratorTest();
}

} // de
