// 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,
  kDrawPicture,
  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() {
    return ExecuteAndSerialize(CanvasRecorderOp::kSave, &Canvas::Save);
  }

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

  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 = {}) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawImageRect), image,
                               source, dest, paint, sampler);
  }

  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 DrawPicture(const Picture& picture) {
    return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPicture),
                               picture);
  }

  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_
