#ifndef _RIVE_RUNTIME_HEADER_HPP_
#define _RIVE_RUNTIME_HEADER_HPP_

#include "core/binary_reader.hpp"
#include <unordered_map>

namespace rive
{
	/// Rive file runtime header. The header is fonud at the beginning of every
	/// Rive runtime file, and begins with a specific 4-byte format: "RIVE".
	/// This is followed by the major and minor version of Rive used to create
	/// the file. Finally the owner and file ids are at the end of header; these
	/// unsigned integers may be zero.
	class RuntimeHeader
	{
	private:
		static constexpr char fingerprint[] = "RIVE";

		int m_MajorVersion;
		int m_MinorVersion;
		int m_FileId;
		std::unordered_map<int, int> m_PropertyToFieldIndex;

	public:
		/// @returns the file's major version
		int majorVersion() const { return m_MajorVersion; }
		/// @returns the file's minor version
		int minorVersion() const { return m_MinorVersion; }
		/// @returns the file's id; may be zero
		int fileId() const { return m_FileId; }

		int propertyFieldId(int propertyKey) const
		{
			auto itr = m_PropertyToFieldIndex.find(propertyKey);
			if (itr == m_PropertyToFieldIndex.end())
			{
				return -1;
			}

			return itr->second;
		}

		/// Reads the header from a binary buffer/
		/// @param reader the binary reader attached to the buffer
		/// @param header a pointer to the header where the data will be stored.
		/// @returns true if the header is successfully read
		static bool read(BinaryReader& reader, RuntimeHeader& header)
		{
			for (int i = 0; i < 4; i++)
			{
				auto b = reader.readByte();
				if (fingerprint[i] != b)
				{
					return false;
				}
			}

			header.m_MajorVersion = (int)reader.readVarUint();
			if (reader.didOverflow())
			{
				return false;
			}
			header.m_MinorVersion = (int)reader.readVarUint();
			if (reader.didOverflow())
			{
				return false;
			}

			header.m_FileId = (int)reader.readVarUint();

			if (reader.didOverflow())
			{
				return false;
			}

			std::vector<int> propertyKeys;
			for (int propertyKey = (int)reader.readVarUint(); propertyKey != 0;
			     propertyKey = (int)reader.readVarUint())
			{
				propertyKeys.push_back(propertyKey);
				if (reader.didOverflow())
				{
					return false;
				}
			}

			int currentInt = 0;
			int currentBit = 8;
			for (auto propertyKey : propertyKeys)
			{
				if (currentBit == 8)
				{
					currentInt = reader.readUint32();
					currentBit = 0;
				}
				int fieldIndex = (currentInt >> currentBit) & 3;
				header.m_PropertyToFieldIndex[propertyKey] = fieldIndex;
				currentBit += 2;
				if (reader.didOverflow())
				{
					return false;
				}
			}

			return true;
		}
	};
} // namespace rive
#endif
