#ifndef _VKALLOCATIONCALLBACKUTIL_HPP
#define _VKALLOCATIONCALLBACKUTIL_HPP
/*-------------------------------------------------------------------------
 * Vulkan CTS Framework
 * --------------------
 *
 * Copyright (c) 2015 Google Inc.
 *
 * 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 Memory allocation callback utilities.
 *//*--------------------------------------------------------------------*/

#include "vkDefs.hpp"
#include "deAppendList.hpp"

#include <vector>
#include <ostream>

namespace tcu
{
class TestLog;
}

namespace vk
{

class AllocationCallbacks
{
public:
									AllocationCallbacks		(void);
	virtual							~AllocationCallbacks	(void);

	virtual void*					allocate				(size_t size, size_t alignment, VkSystemAllocationScope allocationScope) = 0;
	virtual void*					reallocate				(void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope) = 0;
	virtual void					free					(void* mem) = 0;

	virtual void					notifyInternalAllocation(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope) = 0;
	virtual void					notifyInternalFree		(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope) = 0;

	const VkAllocationCallbacks*	getCallbacks			(void) const { return &m_callbacks;	}

private:
	const VkAllocationCallbacks		m_callbacks;
};

struct AllocationCallbackRecord
{
	enum Type
	{
		TYPE_ALLOCATION		= 0,		//! Call to pfnAllocation
		TYPE_REALLOCATION,				//! Call to pfnReallocation
		TYPE_FREE,						//! Call to pfnFree
		TYPE_INTERNAL_ALLOCATION,		//! Call to pfnInternalAllocation
		TYPE_INTERNAL_FREE,				//! Call to pfnInternalFree

		TYPE_LAST
	};

	Type	type;

	union
	{
		struct
		{
			size_t						size;
			size_t						alignment;
			VkSystemAllocationScope		scope;
			void*						returnedPtr;
		} allocation;

		struct
		{
			void*						original;
			size_t						size;
			size_t						alignment;
			VkSystemAllocationScope		scope;
			void*						returnedPtr;
		} reallocation;

		struct
		{
			void*						mem;
		} free;

		// \note Used for both INTERNAL_ALLOCATION and INTERNAL_FREE
		struct
		{
			size_t						size;
			VkInternalAllocationType	type;
			VkSystemAllocationScope		scope;
		} internalAllocation;
	} data;

									AllocationCallbackRecord	(void) : type(TYPE_LAST) {}

	static AllocationCallbackRecord	allocation					(size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr);
	static AllocationCallbackRecord	reallocation				(void* original, size_t size, size_t alignment, VkSystemAllocationScope scope, void* returnedPtr);
	static AllocationCallbackRecord	free						(void* mem);
	static AllocationCallbackRecord	internalAllocation			(size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope);
	static AllocationCallbackRecord	internalFree				(size_t size, VkInternalAllocationType type, VkSystemAllocationScope scope);
};

class ChainedAllocator : public AllocationCallbacks
{
public:
									ChainedAllocator		(const VkAllocationCallbacks* nextAllocator);
									~ChainedAllocator		(void);

	void*							allocate				(size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
	void*							reallocate				(void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
	void							free					(void* mem);

	void							notifyInternalAllocation(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
	void							notifyInternalFree		(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);

private:
	const VkAllocationCallbacks*	m_nextAllocator;
};

class AllocationCallbackRecorder : public ChainedAllocator
{
public:
							AllocationCallbackRecorder	(const VkAllocationCallbacks* allocator, deUint32 callCountHint = 1024);
							~AllocationCallbackRecorder	(void);

	void*					allocate					(size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
	void*					reallocate					(void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
	void					free						(void* mem);

	void					notifyInternalAllocation	(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);
	void					notifyInternalFree			(size_t size, VkInternalAllocationType allocationType, VkSystemAllocationScope allocationScope);

	typedef de::AppendList<AllocationCallbackRecord>::const_iterator	RecordIterator;

	RecordIterator			getRecordsBegin				(void) const { return m_records.begin();	}
	RecordIterator			getRecordsEnd				(void) const { return m_records.end();		}

private:
	typedef de::AppendList<AllocationCallbackRecord> Records;

	Records					m_records;
};

//! Allocator that starts returning null after N allocs
class DeterministicFailAllocator : public ChainedAllocator
{
public:
	enum Mode
	{
		MODE_DO_NOT_COUNT = 0,	//!< Do not count allocations, all allocs will succeed
		MODE_COUNT_AND_FAIL,	//!< Count allocations, fail when reaching alloc N

		MODE_LAST
	};

							DeterministicFailAllocator	(const VkAllocationCallbacks* allocator, deUint32 numPassingAllocs, Mode initialMode);
							~DeterministicFailAllocator	(void);

	void					setMode						(Mode mode);

	void*					allocate					(size_t size, size_t alignment, VkSystemAllocationScope allocationScope);
	void*					reallocate					(void* original, size_t size, size_t alignment, VkSystemAllocationScope allocationScope);

private:
	const deUint32			m_numPassingAllocs;

	Mode					m_mode;
	volatile deUint32		m_allocationNdx;
};

struct AllocationCallbackViolation
{
	enum Reason
	{
		REASON_DOUBLE_FREE = 0,
		REASON_FREE_NOT_ALLOCATED_PTR,
		REASON_REALLOC_NOT_ALLOCATED_PTR,
		REASON_REALLOC_FREED_PTR,
		REASON_NEGATIVE_INTERNAL_ALLOCATION_TOTAL,
		REASON_INVALID_ALLOCATION_SCOPE,
		REASON_INVALID_INTERNAL_ALLOCATION_TYPE,
		REASON_INVALID_ALIGNMENT,
		REASON_REALLOC_DIFFERENT_ALIGNMENT,

		REASON_LAST
	};

	AllocationCallbackRecord	record;
	Reason						reason;

	AllocationCallbackViolation (void)
		: reason(REASON_LAST)
	{}

	AllocationCallbackViolation (const AllocationCallbackRecord& record_, Reason reason_)
		: record(record_)
		, reason(reason_)
	{}
};

struct AllocationCallbackValidationResults
{
	std::vector<AllocationCallbackRecord>		liveAllocations;
	size_t										internalAllocationTotal[VK_INTERNAL_ALLOCATION_TYPE_LAST][VK_SYSTEM_ALLOCATION_SCOPE_LAST];
	std::vector<AllocationCallbackViolation>	violations;

												AllocationCallbackValidationResults	(void);

	void										clear								(void);
};

void							validateAllocationCallbacks		(const AllocationCallbackRecorder& recorder, AllocationCallbackValidationResults* results);
bool							checkAndLog						(tcu::TestLog& log, const AllocationCallbackValidationResults& results, deUint32 allowedLiveAllocScopeBits);
bool							validateAndLog					(tcu::TestLog& log, const AllocationCallbackRecorder& recorder, deUint32 allowedLiveAllocScopeBits);

size_t							getLiveSystemAllocationTotal	(const AllocationCallbackValidationResults& validationResults);

std::ostream&					operator<<						(std::ostream& str, const AllocationCallbackRecord& record);
std::ostream&					operator<<						(std::ostream& str, const AllocationCallbackViolation& violation);

const VkAllocationCallbacks*	getSystemAllocator				(void);

} // vk

#endif // _VKALLOCATIONCALLBACKUTIL_HPP
