/*
 * Copyright 2022 Rive
 */

#ifndef _RIVE_SERIALIZING_FACTORY_HPP_
#define _RIVE_SERIALIZING_FACTORY_HPP_

#include "rive/factory.hpp"
#include "rive/core/vector_binary_writer.hpp"
#include "rive/renderer/cmd/deferred_canvas_host.hpp"
#include <memory>
#include <unordered_map>
#include <vector>

namespace rive
{
namespace gpu
{
class RenderContext;
class RenderCanvas;
} // namespace gpu

// A factory that generates render objects which serialize their rendering
// commands into one buffer that can then be used to replay the commands in a
// viewer app or compare them to ensure that subsequent runs generate the same
// commands.
//
// It is also a DeferredCanvasHost, which is what lets a [silver] test exercise
// cache-as-bitmap: an artboard with a BitmapCache child only rasterizes
// offscreen when its factory answers both renderContext() and
// deferredCanvasHost(). Off by default so existing goldens are untouched --
// call enableBitmapCache() to turn it on.
class SerializingFactory : public Factory, public cmd::DeferredCanvasHost
{
public:
  SerializingFactory();
  ~SerializingFactory() override;

  // Wires the two hooks Artboard::drawCachedAsBitmap requires. The artboard
  // uses renderContext only to mint the offscreen canvas
  // (makeDeferredRenderCanvas), which touches no device, so a null-device
  // context such as RenderContextNULL::MakeContext() is enough. Canvas
  // content then records inline into this factory's stream, bracketed by
  // canvasContentBegin/End, and the composite draws the canvas id.
  void enableBitmapCache(gpu::RenderContext* renderContext);

  Factory* renderContext() override;
  cmd::DeferredCanvasHost* deferredCanvasHost() override;
  cmd::DeferredCanvasHost* canvasContentHost() override;
  // The op is recorded by applyLayerMask below and applied at replay by
  // serialized_replay.cpp, so this host does honour it. Explicit because the
  // capability now defaults to no.
  bool supportsLayerMask() const override { return true; }

  // ---- DeferredCanvasHost ----
  Renderer* beginCanvasContent(gpu::RenderCanvas* canvas, uint32_t clearColor)
      override;
  void endCanvasContent(gpu::RenderCanvas* canvas) override;
  rcp<gpu::RenderCanvas> makeContentCanvas(uint32_t width, uint32_t height)
      override;
  rcp<RenderImage> contentCanvasImage(gpu::RenderCanvas* canvas) override;

  // Stream id for a drawable image. Canvas-backed images are registered
  // here; everything else carries its own id.
  uint64_t imageId(const RenderImage*) const;

  rcp<RenderBuffer> makeRenderBuffer(
      RenderBufferType,
      RenderBufferFlags,
      size_t) override;

  rcp<ImageMeshInstances> makeImageMeshInstances(size_t count) override;

  rcp<RenderShader> makeLinearGradient(
      float sx,
      float sy,
      float ex,
      float ey,
      const ColorInt colors[], // [count]
      const float stops[],     // [count]
      size_t count) override;

  rcp<RenderShader> makeRadialGradient(
      float cx,
      float cy,
      float radius,
      const ColorInt colors[], // [count]
      const float stops[],     // [count]
      size_t count) override;

  rcp<RenderShader> makeAngularGradient(
      const ColorInt colors[], // [count]
      const float stops[],     // [count]
      size_t count) override;

  rcp<RenderPath> makeRenderPath(RawPath&, FillRule) override;

  rcp<RenderPath> makeEmptyRenderPath() override;

  rcp<RenderPaint> makeRenderPaint() override;

  rcp<RenderImage> decodeImage(Span<const uint8_t>) override;

  std::unique_ptr<Renderer> makeRenderer();

  void addFrame();
  void frameSize(uint32_t width, uint32_t height);

  void save(const char* filename);
  bool matches(const char* filename);

  // Recorded SRIV stream for replay via serialized_replay.hpp.
  Span<const uint8_t> bytes() const
  {
    return Span<const uint8_t>(m_buffer.data(), m_buffer.size());
  }

private:
  void saveTarnished(const char* filename);
  // Allocates and records the canvas's id on first sight, then returns it.
  uint64_t canvasId(gpu::RenderCanvas* canvas);

  std::vector<uint8_t> m_buffer;
  VectorBinaryWriter m_writer;

  // Non-null once enableBitmapCache() has run.
  gpu::RenderContext* m_bitmapCacheContext = nullptr;
  // Canvas-backed images live in the same id space as decoded ones so a
  // composite is just an ordinary drawImage. Keyed by pointer, so every
  // canvas ever registered is retained below: a canvas that died could
  // otherwise have its address recycled by the next one and inherit its id,
  // which makes the recording depend on the allocator.
  std::unordered_map<const RenderImage*, uint64_t> m_canvasImageIds;
  std::vector<rcp<gpu::RenderCanvas>> m_retainedCanvases;
  std::unique_ptr<Renderer> m_canvasRenderer;

  uint64_t m_renderImageId = 0;
  uint64_t m_renderPaintId = 0;
  uint64_t m_renderPathId = 0;
  uint64_t m_renderBufferId = 0;
  uint64_t m_renderShaderId = 0;
  uint64_t m_imageMeshInstancesId = 0;
};
} // namespace rive
#endif
