/*
 * Copyright 2019-2020 Hans-Kristian Arntzen
 *
 * 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.
 */

#ifndef SPIRV_CROSS_CONTAINERS_HPP
#define SPIRV_CROSS_CONTAINERS_HPP

#include "spirv_cross_error_handling.hpp"
#include <algorithm>
#include <functional>
#include <iterator>
#include <limits>
#include <memory>
#include <stack>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#ifdef SPIRV_CROSS_NAMESPACE_OVERRIDE
#define SPIRV_CROSS_NAMESPACE SPIRV_CROSS_NAMESPACE_OVERRIDE
#else
#define SPIRV_CROSS_NAMESPACE spirv_cross
#endif

namespace SPIRV_CROSS_NAMESPACE
{
#ifndef SPIRV_CROSS_FORCE_STL_TYPES
// std::aligned_storage does not support size == 0, so roll our own.
template <typename T, size_t N>
class AlignedBuffer
{
public:
	T *data()
	{
#if defined(_MSC_VER) && _MSC_VER < 1900
		// MSVC 2013 workarounds, sigh ...
		// Only use this workaround on MSVC 2013 due to some confusion around default initialized unions.
		// Spec seems to suggest the memory will be zero-initialized, which is *not* what we want.
		return reinterpret_cast<T *>(u.aligned_char);
#else
		return reinterpret_cast<T *>(aligned_char);
#endif
	}

private:
#if defined(_MSC_VER) && _MSC_VER < 1900
	// MSVC 2013 workarounds, sigh ...
	union {
		char aligned_char[sizeof(T) * N];
		double dummy_aligner;
	} u;
#else
	alignas(T) char aligned_char[sizeof(T) * N];
#endif
};

template <typename T>
class AlignedBuffer<T, 0>
{
public:
	T *data()
	{
		return nullptr;
	}
};

// An immutable version of SmallVector which erases type information about storage.
template <typename T>
class VectorView
{
public:
	T &operator[](size_t i) SPIRV_CROSS_NOEXCEPT
	{
		return ptr[i];
	}

	const T &operator[](size_t i) const SPIRV_CROSS_NOEXCEPT
	{
		return ptr[i];
	}

	bool empty() const SPIRV_CROSS_NOEXCEPT
	{
		return buffer_size == 0;
	}

	size_t size() const SPIRV_CROSS_NOEXCEPT
	{
		return buffer_size;
	}

	T *data() SPIRV_CROSS_NOEXCEPT
	{
		return ptr;
	}

	const T *data() const SPIRV_CROSS_NOEXCEPT
	{
		return ptr;
	}

	T *begin() SPIRV_CROSS_NOEXCEPT
	{
		return ptr;
	}

	T *end() SPIRV_CROSS_NOEXCEPT
	{
		return ptr + buffer_size;
	}

	const T *begin() const SPIRV_CROSS_NOEXCEPT
	{
		return ptr;
	}

	const T *end() const SPIRV_CROSS_NOEXCEPT
	{
		return ptr + buffer_size;
	}

	T &front() SPIRV_CROSS_NOEXCEPT
	{
		return ptr[0];
	}

	const T &front() const SPIRV_CROSS_NOEXCEPT
	{
		return ptr[0];
	}

	T &back() SPIRV_CROSS_NOEXCEPT
	{
		return ptr[buffer_size - 1];
	}

	const T &back() const SPIRV_CROSS_NOEXCEPT
	{
		return ptr[buffer_size - 1];
	}

	// Makes it easier to consume SmallVector.
#if defined(_MSC_VER) && _MSC_VER < 1900
	explicit operator std::vector<T>() const
	{
		// Another MSVC 2013 workaround. It does not understand lvalue/rvalue qualified operations.
		return std::vector<T>(ptr, ptr + buffer_size);
	}
#else
	// Makes it easier to consume SmallVector.
	explicit operator std::vector<T>() const &
	{
		return std::vector<T>(ptr, ptr + buffer_size);
	}

	// If we are converting as an r-value, we can pilfer our elements.
	explicit operator std::vector<T>() &&
	{
		return std::vector<T>(std::make_move_iterator(ptr), std::make_move_iterator(ptr + buffer_size));
	}
#endif

	// Avoid sliced copies. Base class should only be read as a reference.
	VectorView(const VectorView &) = delete;
	void operator=(const VectorView &) = delete;

protected:
	VectorView() = default;
	T *ptr = nullptr;
	size_t buffer_size = 0;
};

// Simple vector which supports up to N elements inline, without malloc/free.
// We use a lot of throwaway vectors all over the place which triggers allocations.
// This class only implements the subset of std::vector we need in SPIRV-Cross.
// It is *NOT* a drop-in replacement in general projects.
template <typename T, size_t N = 8>
class SmallVector : public VectorView<T>
{
public:
	SmallVector() SPIRV_CROSS_NOEXCEPT
	{
		this->ptr = stack_storage.data();
		buffer_capacity = N;
	}

	SmallVector(const T *arg_list_begin, const T *arg_list_end) SPIRV_CROSS_NOEXCEPT : SmallVector()
	{
		auto count = size_t(arg_list_end - arg_list_begin);
		reserve(count);
		for (size_t i = 0; i < count; i++, arg_list_begin++)
			new (&this->ptr[i]) T(*arg_list_begin);
		this->buffer_size = count;
	}

	SmallVector(SmallVector &&other) SPIRV_CROSS_NOEXCEPT : SmallVector()
	{
		*this = std::move(other);
	}

	SmallVector &operator=(SmallVector &&other) SPIRV_CROSS_NOEXCEPT
	{
		clear();
		if (other.ptr != other.stack_storage.data())
		{
			// Pilfer allocated pointer.
			if (this->ptr != stack_storage.data())
				free(this->ptr);
			this->ptr = other.ptr;
			this->buffer_size = other.buffer_size;
			buffer_capacity = other.buffer_capacity;
			other.ptr = nullptr;
			other.buffer_size = 0;
			other.buffer_capacity = 0;
		}
		else
		{
			// Need to move the stack contents individually.
			reserve(other.buffer_size);
			for (size_t i = 0; i < other.buffer_size; i++)
			{
				new (&this->ptr[i]) T(std::move(other.ptr[i]));
				other.ptr[i].~T();
			}
			this->buffer_size = other.buffer_size;
			other.buffer_size = 0;
		}
		return *this;
	}

	SmallVector(const SmallVector &other) SPIRV_CROSS_NOEXCEPT : SmallVector()
	{
		*this = other;
	}

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

		clear();
		reserve(other.buffer_size);
		for (size_t i = 0; i < other.buffer_size; i++)
			new (&this->ptr[i]) T(other.ptr[i]);
		this->buffer_size = other.buffer_size;
		return *this;
	}

	explicit SmallVector(size_t count) SPIRV_CROSS_NOEXCEPT : SmallVector()
	{
		resize(count);
	}

	~SmallVector()
	{
		clear();
		if (this->ptr != stack_storage.data())
			free(this->ptr);
	}

	void clear() SPIRV_CROSS_NOEXCEPT
	{
		for (size_t i = 0; i < this->buffer_size; i++)
			this->ptr[i].~T();
		this->buffer_size = 0;
	}

	void push_back(const T &t) SPIRV_CROSS_NOEXCEPT
	{
		reserve(this->buffer_size + 1);
		new (&this->ptr[this->buffer_size]) T(t);
		this->buffer_size++;
	}

	void push_back(T &&t) SPIRV_CROSS_NOEXCEPT
	{
		reserve(this->buffer_size + 1);
		new (&this->ptr[this->buffer_size]) T(std::move(t));
		this->buffer_size++;
	}

	void pop_back() SPIRV_CROSS_NOEXCEPT
	{
		// Work around false positive warning on GCC 8.3.
		// Calling pop_back on empty vector is undefined.
		if (!this->empty())
			resize(this->buffer_size - 1);
	}

	template <typename... Ts>
	void emplace_back(Ts &&... ts) SPIRV_CROSS_NOEXCEPT
	{
		reserve(this->buffer_size + 1);
		new (&this->ptr[this->buffer_size]) T(std::forward<Ts>(ts)...);
		this->buffer_size++;
	}

	void reserve(size_t count) SPIRV_CROSS_NOEXCEPT
	{
		if ((count > std::numeric_limits<size_t>::max() / sizeof(T)) ||
		    (count > std::numeric_limits<size_t>::max() / 2))
		{
			// Only way this should ever happen is with garbage input, terminate.
			std::terminate();
		}

		if (count > buffer_capacity)
		{
			size_t target_capacity = buffer_capacity;
			if (target_capacity == 0)
				target_capacity = 1;
			if (target_capacity < N)
				target_capacity = N;

			// Need to ensure there is a POT value of target capacity which is larger than count,
			// otherwise this will overflow.
			while (target_capacity < count)
				target_capacity <<= 1u;

			T *new_buffer =
			    target_capacity > N ? static_cast<T *>(malloc(target_capacity * sizeof(T))) : stack_storage.data();

			// If we actually fail this malloc, we are hosed anyways, there is no reason to attempt recovery.
			if (!new_buffer)
				std::terminate();

			// In case for some reason two allocations both come from same stack.
			if (new_buffer != this->ptr)
			{
				// We don't deal with types which can throw in move constructor.
				for (size_t i = 0; i < this->buffer_size; i++)
				{
					new (&new_buffer[i]) T(std::move(this->ptr[i]));
					this->ptr[i].~T();
				}
			}

			if (this->ptr != stack_storage.data())
				free(this->ptr);
			this->ptr = new_buffer;
			buffer_capacity = target_capacity;
		}
	}

	void insert(T *itr, const T *insert_begin, const T *insert_end) SPIRV_CROSS_NOEXCEPT
	{
		auto count = size_t(insert_end - insert_begin);
		if (itr == this->end())
		{
			reserve(this->buffer_size + count);
			for (size_t i = 0; i < count; i++, insert_begin++)
				new (&this->ptr[this->buffer_size + i]) T(*insert_begin);
			this->buffer_size += count;
		}
		else
		{
			if (this->buffer_size + count > buffer_capacity)
			{
				auto target_capacity = this->buffer_size + count;
				if (target_capacity == 0)
					target_capacity = 1;
				if (target_capacity < N)
					target_capacity = N;

				while (target_capacity < count)
					target_capacity <<= 1u;

				// Need to allocate new buffer. Move everything to a new buffer.
				T *new_buffer =
				    target_capacity > N ? static_cast<T *>(malloc(target_capacity * sizeof(T))) : stack_storage.data();

				// If we actually fail this malloc, we are hosed anyways, there is no reason to attempt recovery.
				if (!new_buffer)
					std::terminate();

				// First, move elements from source buffer to new buffer.
				// We don't deal with types which can throw in move constructor.
				auto *target_itr = new_buffer;
				auto *original_source_itr = this->begin();

				if (new_buffer != this->ptr)
				{
					while (original_source_itr != itr)
					{
						new (target_itr) T(std::move(*original_source_itr));
						original_source_itr->~T();
						++original_source_itr;
						++target_itr;
					}
				}

				// Copy-construct new elements.
				for (auto *source_itr = insert_begin; source_itr != insert_end; ++source_itr, ++target_itr)
					new (target_itr) T(*source_itr);

				// Move over the other half.
				if (new_buffer != this->ptr || insert_begin != insert_end)
				{
					while (original_source_itr != this->end())
					{
						new (target_itr) T(std::move(*original_source_itr));
						original_source_itr->~T();
						++original_source_itr;
						++target_itr;
					}
				}

				if (this->ptr != stack_storage.data())
					free(this->ptr);
				this->ptr = new_buffer;
				buffer_capacity = target_capacity;
			}
			else
			{
				// Move in place, need to be a bit careful about which elements are constructed and which are not.
				// Move the end and construct the new elements.
				auto *target_itr = this->end() + count;
				auto *source_itr = this->end();
				while (target_itr != this->end() && source_itr != itr)
				{
					--target_itr;
					--source_itr;
					new (target_itr) T(std::move(*source_itr));
				}

				// For already constructed elements we can move-assign.
				std::move_backward(itr, source_itr, target_itr);

				// For the inserts which go to already constructed elements, we can do a plain copy.
				while (itr != this->end() && insert_begin != insert_end)
					*itr++ = *insert_begin++;

				// For inserts into newly allocated memory, we must copy-construct instead.
				while (insert_begin != insert_end)
				{
					new (itr) T(*insert_begin);
					++itr;
					++insert_begin;
				}
			}

			this->buffer_size += count;
		}
	}

	void insert(T *itr, const T &value) SPIRV_CROSS_NOEXCEPT
	{
		insert(itr, &value, &value + 1);
	}

	T *erase(T *itr) SPIRV_CROSS_NOEXCEPT
	{
		std::move(itr + 1, this->end(), itr);
		this->ptr[--this->buffer_size].~T();
		return itr;
	}

	void erase(T *start_erase, T *end_erase) SPIRV_CROSS_NOEXCEPT
	{
		if (end_erase == this->end())
		{
			resize(size_t(start_erase - this->begin()));
		}
		else
		{
			auto new_size = this->buffer_size - (end_erase - start_erase);
			std::move(end_erase, this->end(), start_erase);
			resize(new_size);
		}
	}

	void resize(size_t new_size) SPIRV_CROSS_NOEXCEPT
	{
		if (new_size < this->buffer_size)
		{
			for (size_t i = new_size; i < this->buffer_size; i++)
				this->ptr[i].~T();
		}
		else if (new_size > this->buffer_size)
		{
			reserve(new_size);
			for (size_t i = this->buffer_size; i < new_size; i++)
				new (&this->ptr[i]) T();
		}

		this->buffer_size = new_size;
	}

private:
	size_t buffer_capacity = 0;
	AlignedBuffer<T, N> stack_storage;
};

// A vector without stack storage.
// Could also be a typedef-ed to std::vector,
// but might as well use the one we have.
template <typename T>
using Vector = SmallVector<T, 0>;

#else // SPIRV_CROSS_FORCE_STL_TYPES

template <typename T, size_t N = 8>
using SmallVector = std::vector<T>;
template <typename T>
using Vector = std::vector<T>;
template <typename T>
using VectorView = std::vector<T>;

#endif // SPIRV_CROSS_FORCE_STL_TYPES

// An object pool which we use for allocating IVariant-derived objects.
// We know we are going to allocate a bunch of objects of each type,
// so amortize the mallocs.
class ObjectPoolBase
{
public:
	virtual ~ObjectPoolBase() = default;
	virtual void free_opaque(void *ptr) = 0;
};

template <typename T>
class ObjectPool : public ObjectPoolBase
{
public:
	explicit ObjectPool(unsigned start_object_count_ = 16)
	    : start_object_count(start_object_count_)
	{
	}

	template <typename... P>
	T *allocate(P &&... p)
	{
		if (vacants.empty())
		{
			unsigned num_objects = start_object_count << memory.size();
			T *ptr = static_cast<T *>(malloc(num_objects * sizeof(T)));
			if (!ptr)
				return nullptr;

			for (unsigned i = 0; i < num_objects; i++)
				vacants.push_back(&ptr[i]);

			memory.emplace_back(ptr);
		}

		T *ptr = vacants.back();
		vacants.pop_back();
		new (ptr) T(std::forward<P>(p)...);
		return ptr;
	}

	void free(T *ptr)
	{
		ptr->~T();
		vacants.push_back(ptr);
	}

	void free_opaque(void *ptr) override
	{
		free(static_cast<T *>(ptr));
	}

	void clear()
	{
		vacants.clear();
		memory.clear();
	}

protected:
	Vector<T *> vacants;

	struct MallocDeleter
	{
		void operator()(T *ptr)
		{
			::free(ptr);
		}
	};

	SmallVector<std::unique_ptr<T, MallocDeleter>> memory;
	unsigned start_object_count;
};

template <size_t StackSize = 4096, size_t BlockSize = 4096>
class StringStream
{
public:
	StringStream()
	{
		reset();
	}

	~StringStream()
	{
		reset();
	}

	// Disable copies and moves. Makes it easier to implement, and we don't need it.
	StringStream(const StringStream &) = delete;
	void operator=(const StringStream &) = delete;

	template <typename T, typename std::enable_if<!std::is_floating_point<T>::value, int>::type = 0>
	StringStream &operator<<(const T &t)
	{
		auto s = std::to_string(t);
		append(s.data(), s.size());
		return *this;
	}

	// Only overload this to make float/double conversions ambiguous.
	StringStream &operator<<(uint32_t v)
	{
		auto s = std::to_string(v);
		append(s.data(), s.size());
		return *this;
	}

	StringStream &operator<<(char c)
	{
		append(&c, 1);
		return *this;
	}

	StringStream &operator<<(const std::string &s)
	{
		append(s.data(), s.size());
		return *this;
	}

	StringStream &operator<<(const char *s)
	{
		append(s, strlen(s));
		return *this;
	}

	template <size_t N>
	StringStream &operator<<(const char (&s)[N])
	{
		append(s, strlen(s));
		return *this;
	}

	std::string str() const
	{
		std::string ret;
		size_t target_size = 0;
		for (auto &saved : saved_buffers)
			target_size += saved.offset;
		target_size += current_buffer.offset;
		ret.reserve(target_size);

		for (auto &saved : saved_buffers)
			ret.insert(ret.end(), saved.buffer, saved.buffer + saved.offset);
		ret.insert(ret.end(), current_buffer.buffer, current_buffer.buffer + current_buffer.offset);
		return ret;
	}

	void reset()
	{
		for (auto &saved : saved_buffers)
			if (saved.buffer != stack_buffer)
				free(saved.buffer);
		if (current_buffer.buffer != stack_buffer)
			free(current_buffer.buffer);

		saved_buffers.clear();
		current_buffer.buffer = stack_buffer;
		current_buffer.offset = 0;
		current_buffer.size = sizeof(stack_buffer);
	}

private:
	struct Buffer
	{
		char *buffer = nullptr;
		size_t offset = 0;
		size_t size = 0;
	};
	Buffer current_buffer;
	char stack_buffer[StackSize];
	SmallVector<Buffer> saved_buffers;

	void append(const char *s, size_t len)
	{
		size_t avail = current_buffer.size - current_buffer.offset;
		if (avail < len)
		{
			if (avail > 0)
			{
				memcpy(current_buffer.buffer + current_buffer.offset, s, avail);
				s += avail;
				len -= avail;
				current_buffer.offset += avail;
			}

			saved_buffers.push_back(current_buffer);
			size_t target_size = len > BlockSize ? len : BlockSize;
			current_buffer.buffer = static_cast<char *>(malloc(target_size));
			if (!current_buffer.buffer)
				SPIRV_CROSS_THROW("Out of memory.");

			memcpy(current_buffer.buffer, s, len);
			current_buffer.offset = len;
			current_buffer.size = target_size;
		}
		else
		{
			memcpy(current_buffer.buffer + current_buffer.offset, s, len);
			current_buffer.offset += len;
		}
	}
};

} // namespace SPIRV_CROSS_NAMESPACE

#endif
