#ifndef _RIVE_TESTS_RIV_BYTES_HPP_
#define _RIVE_TESTS_RIV_BYTES_HPP_

#include "rive/core/vector_binary_writer.hpp"
#include "rive/file.hpp"
#include "rive/generated/artboard_base.hpp"
#include "rive/generated/backboard_base.hpp"
#include "rive/generated/component_base.hpp"
#include "rive/generated/layout_component_base.hpp"

#include <map>
#include <string>
#include <vector>

// A minimal .riv assembled by hand, so an object or a property can be placed
// where no exporter would put it -- which is how the import paths that only
// a malformed or forward-dated file reaches get exercised.
class RivBytes
{
public:
  RivBytes() : m_writer(&m_objects) {}

  void object(uint16_t typeKey) { m_writer.writeVarUint((uint64_t)typeKey); }
  void end() { m_writer.writeVarUint((uint64_t)0); }

  // ToC field ids: 0 uint (bools ride as uints), 1 string, 2 double.
  void propUint(uint16_t key, uint64_t value)
  {
    m_toc[key] = 0;
    m_writer.writeVarUint((uint64_t)key);
    m_writer.writeVarUint(value);
  }
  void propBool(uint16_t key, bool value)
  {
    m_toc[key] = 0;
    m_writer.writeVarUint((uint64_t)key);
    m_writer.write((uint8_t)(value ? 1 : 0));
  }
  void propString(uint16_t key, const std::string& value)
  {
    m_toc[key] = 1;
    m_writer.writeVarUint((uint64_t)key);
    m_writer.write(value);
  }
  void propFloat(uint16_t key, float value)
  {
    m_toc[key] = 2;
    m_writer.writeVarUint((uint64_t)key);
    m_writer.write(value);
  }
  // A key the file's ToC does not describe.
  void propUintOutsideToc(uint16_t key, uint64_t value)
  {
    m_writer.writeVarUint((uint64_t)key);
    m_writer.writeVarUint(value);
  }

  std::vector<uint8_t> bytes() const
  {
    std::vector<uint8_t> out;
    rive::VectorBinaryWriter writer(&out);
    writer.write((const uint8_t*)"RIVE", 4);
    writer.writeVarUint((uint64_t)rive::File::majorVersion);
    writer.writeVarUint((uint64_t)rive::File::minorVersion);
    writer.writeVarUint((uint64_t)0); // file id
    for (const auto& entry : m_toc)
    {
      writer.writeVarUint((uint64_t)entry.first);
    }
    writer.writeVarUint((uint64_t)0);
    // The reader refreshes its packed int every 8 bits: one uint32 per
    // four keys (RuntimeHeader::read).
    uint32_t packed = 0;
    int bit = 0;
    for (const auto& entry : m_toc)
    {
      packed |= entry.second << bit;
      bit += 2;
      if (bit == 8)
      {
        writer.write(packed);
        packed = 0;
        bit = 0;
      }
    }
    if (bit != 0)
    {
      writer.write(packed);
    }
    out.insert(out.end(), m_objects.begin(), m_objects.end());
    return out;
  }

private:
  std::vector<uint8_t> m_objects;
  rive::VectorBinaryWriter m_writer;
  std::map<uint16_t, uint32_t> m_toc;
};

// One 100x100 artboard named "A", with no Backboard of its own -- for streams
// that need to place something between the two.
inline void writeArtboardObject(RivBytes& riv)
{
  riv.object(rive::ArtboardBase::typeKey);
  riv.propString(rive::ComponentBase::namePropertyKey, "A");
  riv.propFloat(rive::LayoutComponentBase::widthPropertyKey, 100.0f);
  riv.propFloat(rive::LayoutComponentBase::heightPropertyKey, 100.0f);
  riv.end();
}

// The smallest loadable file: a Backboard and one 100x100 artboard named "A".
inline void writeArtboard(RivBytes& riv)
{
  riv.object(rive::BackboardBase::typeKey);
  riv.end();
  writeArtboardObject(riv);
}

#endif
