#ifndef _RIVE_RUNTIME_HEADER_HPP_
#define _RIVE_RUNTIME_HEADER_HPP_

#include "rive/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 = reader.readVarUintAs<int>();
            if (reader.didOverflow()) {
                return false;
            }
            header.m_MinorVersion = reader.readVarUintAs<int>();
            if (reader.didOverflow()) {
                return false;
            }

            header.m_FileId = reader.readVarUintAs<int>();

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

            std::vector<int> propertyKeys;
            for (int propertyKey = reader.readVarUintAs<int>(); propertyKey != 0;
                 propertyKey = reader.readVarUintAs<int>())
            {
                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
