// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_IMPELLER_AIKS_CANVAS_RECORDER_H_
#define FLUTTER_IMPELLER_AIKS_CANVAS_RECORDER_H_

#include <cstdint>

#include "impeller/aiks/canvas.h"

#define FLT_CANVAS_RECORDER_OP_ARG(name) \
  CanvasRecorderOp::k##name, &Canvas::name

namespace impeller {
/// TODO(tbd): These are very similar to `flutter::DisplayListOpType`. When
/// golden tests can be written at a higher level, migrate these to
/// flutter::DisplayListOpType.
enum CanvasRecorderOp : uint16_t {
  kNew,
  kSave,
  kSaveLayer,
  kRestore,
  kRestoreToCount,
  kResetTransform,
  kTransform,
  kConcat,
  kPreConcat,
  kTranslate,
  kScale2,
  kScale3,
  kSkew,
  kRotate,
  kDrawPath,
  kDrawPaint,
  kDrawLine,
  kDrawRect,
  kDrawOval,
  kDrawRRect,
  kDrawCircle,
  kDrawPoints,
  kDrawImage,
  kDrawImageRect,
  kClipPath,
  kClipRect,
  kClipOval,
  kClipRRect,
  kDrawTextFrame,
  kDrawVertices,
  kDrawAtlas,
};

// Canvas recorder should only be used when IMPELLER_TRACE_CANVAS is defined
// (never in production code).
#ifdef IMPELLER_TRACE_CANVAS
/// Static polymorphic replacement for impeller::Canvas that records methods
/// called on an impeller::Canvas and forwards it to a real instance.
/// TODO(https://github.com/flutter/flutter/issues/135718): Move this recorder
/// to the DisplayList level when golden tests can be written at the ui.Canvas
/// layer.
template <typename Serializer>
class CanvasRecorder {
 public:
  CanvasRecorder() : canvas_() { serializer_.Write(CanvasRecorderOp::kNew); }

  explicit CanvasRecorder(Rect cull_rect) : canvas_(cull_rect) {
    serializer_.Write(CanvasRecorderOp::kNew);
  }

  explicit CanvasRecorder(IRect cull_rect) : canvas_(cull_rect) {
    serializer_.Write(CanvasRecorderOp::kNew);
  }

  ~CanvasRecorder() {}

  const Serializer& GetSerializer() const { return serializer_; }

  template <typename ReturnType>
  ReturnType ExecuteAndSerialize(CanvasRecorderOp op,
                                 ReturnType (Canvas::*canvasMethod)()) {
    serializer_.Write(op);
    return (canvas_.*canvasMethod)();
  }

  template <typename FuncType, typename... Args>
  auto ExecuteAndSerialize(CanvasRecorderOp op,
                           FuncType canvasMethod,
                           Args&&... args)
      -> decltype((std::declval<Canvas>().*
                   canvasMethod)(std::forward<Args>(args)...)) {
    // Serialize each argument
    (serializer_.Write(std::forward<Args>(args)), ...);
    serializer_.Write(op);
    return (canvas_.*canvasMethod)(std::forward<Args>(args)...);
  }

  template <typename FuncType, typename... Args>
  auto ExecuteAndSkipArgSerialize(CanvasRecorderOp op,
                                  FuncType canvasMethod,
                                  Args&&... args)
      -> decltype((std::declval<Canvas>().*
                   canvasMethod)(std::forward<Args>(args)...)) {
    serializer_.Write(op);
    return (canvas_.*canvasMethod)(std::forward<Args>(args)...);
  }

  //////////////////////////////////////////////////////////////////////////////
  // Canvas Static Polymorphism
  // ////////////////////////////////////////////////
  //////////////////////////////////////////////////////////////////////////////

  void Save(uint32_t total_content_depth = Canvas::kMaxDepth) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Save),
                               total_content_depth);
  }

  void SaveLayer(
      const Paint& paint,
      std::optional<Rect> bounds = std::nullopt,
      const std::shared_ptr<ImageFilter>& backdrop_filter = nullptr,
      ContentBoundsPromise bounds_promise = ContentBoundsPromise::kUnknown,
      uint32_t total_content_depth = Canvas::kMaxDepth) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(SaveLayer), paint,
                               bounds, backdrop_filter, bounds_promise,
                               total_content_depth);
  }

  bool Restore() {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Restore));
  }

  size_t GetSaveCount() const { return canvas_.GetSaveCount(); }

  void RestoreToCount(size_t count) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(RestoreToCount),
                               count);
  }

  const Matrix& GetCurrentTransform() const {
    return canvas_.GetCurrentTransform();
  }

  const std::optional<Rect> GetCurrentLocalCullingBounds() const {
    return canvas_.GetCurrentLocalCullingBounds();
  }

  void ResetTransform() {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ResetTransform));
  }

  void Transform(const Matrix& transform) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Transform),
                               transform);
  }

  void Concat(const Matrix& transform) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Concat), transform);
  }

  void PreConcat(const Matrix& transform) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(PreConcat),
                               transform);
  }

  void Translate(const Vector3& offset) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Translate), offset);
  }

  void Scale(const Vector2& scale) {
    return ExecuteAndSerialize(
        CanvasRecorderOp::kScale2,
        static_cast<void (Canvas::*)(const Vector2&)>(&Canvas::Scale), scale);
  }

  void Scale(const Vector3& scale) {
    return ExecuteAndSerialize(
        CanvasRecorderOp::kScale3,
        static_cast<void (Canvas::*)(const Vector3&)>(&Canvas::Scale), scale);
  }

  void Skew(Scalar sx, Scalar sy) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Skew), sx, sy);
  }

  void Rotate(Radians radians) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Rotate), radians);
  }

  void DrawPath(Path path, const Paint& paint) {
    serializer_.Write(path);
    serializer_.Write(paint);
    return ExecuteAndSkipArgSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPath),
                                      std::move(path), paint);
  }

  void DrawPaint(const Paint& paint) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPaint), paint);
  }

  void DrawLine(const Point& p0, const Point& p1, const Paint& paint) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawLine), p0, p1,
                               paint);
  }

  void DrawRect(Rect rect, const Paint& paint) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawRect), rect,
                               paint);
  }

  void DrawOval(const Rect& rect, const Paint& paint) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawOval), rect,
                               paint);
  }

  void DrawRRect(const Rect& rect,
                 const Size& corner_radii,
                 const Paint& paint) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawRRect), rect,
                               corner_radii, paint);
  }

  void DrawCircle(Point center, Scalar radius, const Paint& paint) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawCircle), center,
                               radius, paint);
  }

  void DrawPoints(std::vector<Point> points,
                  Scalar radius,
                  const Paint& paint,
                  PointStyle point_style) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPoints), points,
                               radius, paint, point_style);
  }

  void DrawImage(const std::shared_ptr<Image>& image,
                 Point offset,
                 const Paint& paint,
                 SamplerDescriptor sampler = {}) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawImage), image,
                               offset, paint, sampler);
  }

  void DrawImageRect(
      const std::shared_ptr<Image>& image,
      Rect source,
      Rect dest,
      const Paint& paint,
      SamplerDescriptor sampler = {},
      SourceRectConstraint src_rect_constraint = SourceRectConstraint::kFast) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawImageRect), image,
                               source, dest, paint, sampler,
                               src_rect_constraint);
  }

  void ClipPath(
      Path path,
      Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect) {
    serializer_.Write(path);
    serializer_.Write(clip_op);
    return ExecuteAndSkipArgSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipPath),
                                      std::move(path), clip_op);
  }

  void ClipRect(
      const Rect& rect,
      Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipRect), rect,
                               clip_op);
  }

  void ClipOval(
      const Rect& bounds,
      Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipOval), bounds,
                               clip_op);
  }

  void ClipRRect(
      const Rect& rect,
      const Size& corner_radii,
      Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipRRect), rect,
                               corner_radii, clip_op);
  }

  void DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
                     Point position,
                     const Paint& paint) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawTextFrame),
                               text_frame, position, paint);
  }

  void DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
                    BlendMode blend_mode,
                    const Paint& paint) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawVertices),
                               vertices, blend_mode, paint);
  }

  void DrawAtlas(const std::shared_ptr<Image>& atlas,
                 std::vector<Matrix> transforms,
                 std::vector<Rect> texture_coordinates,
                 std::vector<Color> colors,
                 BlendMode blend_mode,
                 SamplerDescriptor sampler,
                 std::optional<Rect> cull_rect,
                 const Paint& paint) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawAtlas),  //
                               atlas,                                  //
                               transforms,                             //
                               texture_coordinates,                    //
                               colors,                                 //
                               blend_mode,                             //
                               sampler,                                //
                               cull_rect,                              //
                               paint);
  }

  Picture EndRecordingAsPicture() { return canvas_.EndRecordingAsPicture(); }

 private:
  Canvas canvas_;
  Serializer serializer_;
};
#endif

}  // namespace impeller

#endif  // FLUTTER_IMPELLER_AIKS_CANVAS_RECORDER_H_
