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

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

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

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