/*-------------------------------------------------------------------------
 * 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 buffer
 *//*--------------------------------------------------------------------*/

#include "deArrayBuffer.hpp"

#if defined(DE_VALGRIND_BUILD) && defined(HAVE_VALGRIND_MEMCHECK_H)
#	include <valgrind/memcheck.h>
#endif

namespace de
{
namespace detail
{

void* ArrayBuffer_AlignedMalloc (size_t numBytes, size_t alignment)
{
	const int	sizeAsInt	= (int)numBytes;
	void*		ptr;

	// int overflow
	if (sizeAsInt < 0 || numBytes != (size_t)sizeAsInt)
		throw std::bad_alloc();

	// alloc
	ptr = deAlignedMalloc(sizeAsInt, (int)alignment);
	if (!ptr)
		throw std::bad_alloc();

	// mark area as undefined for valgrind
#if defined(DE_VALGRIND_BUILD) && defined(HAVE_VALGRIND_MEMCHECK_H)
	if (RUNNING_ON_VALGRIND)
	{
		VALGRIND_MAKE_MEM_UNDEFINED(ptr, numBytes);
	}
#endif

	return ptr;
}

void ArrayBuffer_AlignedFree (void* ptr)
{
	deAlignedFree(ptr);
}

} // detail

void ArrayBuffer_selfTest (void)
{
	// default constructor
	{
		de::ArrayBuffer<int> buf;
		DE_TEST_ASSERT(buf.size() == 0);
		DE_TEST_ASSERT(buf.getPtr() == DE_NULL);
	}

	// sized constructor
	{
		de::ArrayBuffer<int> buf(4);
		DE_TEST_ASSERT(buf.size() == 4);
		DE_TEST_ASSERT(buf.getPtr() != DE_NULL);
	}

	// copy constructor
	{
		de::ArrayBuffer<int> originalBuf(4);
		*originalBuf.getElementPtr(0) = 1;
		*originalBuf.getElementPtr(1) = 2;
		*originalBuf.getElementPtr(2) = 3;
		*originalBuf.getElementPtr(3) = 4;

		de::ArrayBuffer<int> targetBuf(originalBuf);

		DE_TEST_ASSERT(*originalBuf.getElementPtr(0) == 1);
		DE_TEST_ASSERT(*originalBuf.getElementPtr(1) == 2);
		DE_TEST_ASSERT(*originalBuf.getElementPtr(2) == 3);
		DE_TEST_ASSERT(*originalBuf.getElementPtr(3) == 4);

		DE_TEST_ASSERT(*targetBuf.getElementPtr(0) == 1);
		DE_TEST_ASSERT(*targetBuf.getElementPtr(1) == 2);
		DE_TEST_ASSERT(*targetBuf.getElementPtr(2) == 3);
		DE_TEST_ASSERT(*targetBuf.getElementPtr(3) == 4);
	}

	// assignment
	{
		de::ArrayBuffer<int> originalBuf(4);
		*originalBuf.getElementPtr(0) = 1;
		*originalBuf.getElementPtr(1) = 2;
		*originalBuf.getElementPtr(2) = 3;
		*originalBuf.getElementPtr(3) = 4;

		de::ArrayBuffer<int> targetBuf(1);

		targetBuf = originalBuf;

		DE_TEST_ASSERT(*originalBuf.getElementPtr(0) == 1);
		DE_TEST_ASSERT(*originalBuf.getElementPtr(1) == 2);
		DE_TEST_ASSERT(*originalBuf.getElementPtr(2) == 3);
		DE_TEST_ASSERT(*originalBuf.getElementPtr(3) == 4);

		DE_TEST_ASSERT(*targetBuf.getElementPtr(0) == 1);
		DE_TEST_ASSERT(*targetBuf.getElementPtr(1) == 2);
		DE_TEST_ASSERT(*targetBuf.getElementPtr(2) == 3);
		DE_TEST_ASSERT(*targetBuf.getElementPtr(3) == 4);
	}

	// clear
	{
		de::ArrayBuffer<int> buf(4);
		buf.clear();
		DE_TEST_ASSERT(buf.size() == 0);
		DE_TEST_ASSERT(buf.getPtr() == DE_NULL);
	}

	// setStorage
	{
		de::ArrayBuffer<int> buf(4);
		buf.setStorage(12);
		DE_TEST_ASSERT(buf.size() == 12);
		DE_TEST_ASSERT(buf.getPtr() != DE_NULL);
	}

	// setStorage, too large
	{
		de::ArrayBuffer<int> buf(4);
		*buf.getElementPtr(0) = 1;
		*buf.getElementPtr(1) = 2;
		*buf.getElementPtr(2) = 3;
		*buf.getElementPtr(3) = 4;

		try
		{
			buf.setStorage((size_t)-1);

			// setStorage succeeded, all ok
		}
		catch (std::bad_alloc&)
		{
			// alloc failed, check storage not changed

			DE_TEST_ASSERT(buf.size() == 4);
			DE_TEST_ASSERT(*buf.getElementPtr(0) == 1);
			DE_TEST_ASSERT(*buf.getElementPtr(1) == 2);
			DE_TEST_ASSERT(*buf.getElementPtr(2) == 3);
			DE_TEST_ASSERT(*buf.getElementPtr(3) == 4);
		}
	}

	// swap
	{
		de::ArrayBuffer<int> buf;
		de::ArrayBuffer<int> source(4);
		*source.getElementPtr(0) = 1;
		*source.getElementPtr(1) = 2;
		*source.getElementPtr(2) = 3;
		*source.getElementPtr(3) = 4;

		buf.swap(source);

		DE_TEST_ASSERT(source.size() == 0);
		DE_TEST_ASSERT(buf.size() == 4);
		DE_TEST_ASSERT(*buf.getElementPtr(0) == 1);
		DE_TEST_ASSERT(*buf.getElementPtr(1) == 2);
		DE_TEST_ASSERT(*buf.getElementPtr(2) == 3);
		DE_TEST_ASSERT(*buf.getElementPtr(3) == 4);
	}

	// default
	{
		de::ArrayBuffer<int> source(4);
		int dst;
		*source.getElementPtr(1) = 2;

		deMemcpy(&dst, (int*)source.getPtr() + 1, sizeof(int));

		DE_TEST_ASSERT(dst == 2);
	}

	// Aligned
	{
		de::ArrayBuffer<int, 64, sizeof(int)> source(4);
		int dst;
		*source.getElementPtr(1) = 2;

		deMemcpy(&dst, (int*)source.getPtr() + 1, sizeof(int));

		DE_TEST_ASSERT(dst == 2);
	}

	// Strided
	{
		de::ArrayBuffer<int, 4, 64> source(4);
		int dst;
		*source.getElementPtr(1) = 2;

		deMemcpy(&dst, (deUint8*)source.getPtr() + 64, sizeof(int));

		DE_TEST_ASSERT(dst == 2);
	}

	// Aligned, Strided
	{
		de::ArrayBuffer<int, 32, 64> source(4);
		int dst;
		*source.getElementPtr(1) = 2;

		deMemcpy(&dst, (deUint8*)source.getPtr() + 64, sizeof(int));

		DE_TEST_ASSERT(dst == 2);
	}
}

} // de
