// 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.

#include "flutter/testing/mock_canvas.h"

#include "flutter/fml/logging.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSerialProcs.h"
#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkTextBlob.h"

namespace flutter {
namespace testing {

constexpr SkISize kSize = SkISize::Make(64, 64);

MockCanvas::MockCanvas()
    : SkCanvasVirtualEnforcer<SkCanvas>(kSize.fWidth, kSize.fHeight),
      internal_canvas_(imageInfo().width(), imageInfo().height()),
      current_layer_(0) {
  internal_canvas_.addCanvas(this);
}

MockCanvas::~MockCanvas() {
  EXPECT_EQ(current_layer_, 0);
}

void MockCanvas::willSave() {
  draw_calls_.emplace_back(
      DrawCall{current_layer_, SaveData{current_layer_ + 1}});
  current_layer_++;  // Must go here; func params order of eval is undefined
}

SkCanvas::SaveLayerStrategy MockCanvas::getSaveLayerStrategy(
    const SaveLayerRec& rec) {
  // saveLayer calls this prior to running, so we use it to track saveLayer
  // calls
  draw_calls_.emplace_back(DrawCall{
      current_layer_,
      SaveLayerData{rec.fBounds ? *rec.fBounds : SkRect(),
                    rec.fPaint ? *rec.fPaint : SkPaint(),
                    rec.fBackdrop ? sk_ref_sp<SkImageFilter>(rec.fBackdrop)
                                  : sk_sp<SkImageFilter>(),
                    current_layer_ + 1}});
  current_layer_++;  // Must go here; func params order of eval is undefined
  return kNoLayer_SaveLayerStrategy;
}

void MockCanvas::willRestore() {
  FML_DCHECK(current_layer_ > 0);

  draw_calls_.emplace_back(
      DrawCall{current_layer_, RestoreData{current_layer_ - 1}});
  current_layer_--;  // Must go here; func params order of eval is undefined
}

#ifdef SK_SUPPORT_LEGACY_CANVASMATRIX33
void MockCanvas::didConcat(const SkMatrix& matrix) {
  this->didConcat44(SkM44(matrix));
}
void MockCanvas::didSetMatrix(const SkMatrix& matrix) {
  this->didSetM44(SkM44(matrix));
}
#endif

void MockCanvas::didConcat44(const SkM44& matrix) {
  draw_calls_.emplace_back(DrawCall{current_layer_, ConcatMatrixData{matrix}});
}

void MockCanvas::didSetM44(const SkM44& matrix) {
  draw_calls_.emplace_back(DrawCall{current_layer_, SetMatrixData{matrix}});
}

void MockCanvas::didScale(SkScalar x, SkScalar y) {
  this->didConcat44(SkM44::Scale(x, y));
}

void MockCanvas::didTranslate(SkScalar x, SkScalar y) {
  this->didConcat44(SkM44::Translate(x, y));
}

void MockCanvas::onDrawTextBlob(const SkTextBlob* text,
                                SkScalar x,
                                SkScalar y,
                                const SkPaint& paint) {
  // This duplicates existing logic in SkCanvas::onDrawPicture
  // that should probably be split out so it doesn't need to be here as well.
  SkRect storage;
  const SkRect* bounds = nullptr;
  if (paint.canComputeFastBounds()) {
    storage = text->bounds().makeOffset(x, y);
    SkRect tmp;
    if (this->quickReject(paint.computeFastBounds(storage, &tmp))) {
      return;
    }
    bounds = &storage;
  }

  draw_calls_.emplace_back(DrawCall{
      current_layer_, DrawTextData{text ? text->serialize(SkSerialProcs{})
                                        : SkData::MakeUninitialized(0),
                                   paint, SkPoint::Make(x, y)}});
}

void MockCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
  draw_calls_.emplace_back(DrawCall{current_layer_, DrawRectData{rect, paint}});
}

void MockCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
  draw_calls_.emplace_back(DrawCall{current_layer_, DrawPathData{path, paint}});
}

void MockCanvas::onDrawShadowRec(const SkPath& path,
                                 const SkDrawShadowRec& rec) {
  (void)rec;  // Can't use b/c Skia keeps this type anonymous.
  draw_calls_.emplace_back(DrawCall{current_layer_, DrawShadowData{path}});
}

void MockCanvas::onDrawPicture(const SkPicture* picture,
                               const SkMatrix* matrix,
                               const SkPaint* paint) {
  // This duplicates existing logic in SkCanvas::onDrawPicture
  // that should probably be split out so it doesn't need to be here as well.
  if (!paint || paint->canComputeFastBounds()) {
    SkRect bounds = picture->cullRect();
    if (paint) {
      paint->computeFastBounds(bounds, &bounds);
    }
    if (matrix) {
      matrix->mapRect(&bounds);
    }
    if (this->quickReject(bounds)) {
      return;
    }
  }

  draw_calls_.emplace_back(DrawCall{
      current_layer_,
      DrawPictureData{
          picture ? picture->serialize() : SkData::MakeUninitialized(0),
          paint ? *paint : SkPaint(), matrix ? *matrix : SkMatrix()}});
}

void MockCanvas::onClipRect(const SkRect& rect,
                            SkClipOp op,
                            ClipEdgeStyle style) {
  draw_calls_.emplace_back(
      DrawCall{current_layer_, ClipRectData{rect, op, style}});
  // quickReject() is handled by base class and needs accurate clip information
  SkCanvas::onClipRect(rect, op, style);
}

void MockCanvas::onClipRRect(const SkRRect& rrect,
                             SkClipOp op,
                             ClipEdgeStyle style) {
  draw_calls_.emplace_back(
      DrawCall{current_layer_, ClipRRectData{rrect, op, style}});
  // quickReject() is handled by base class and needs accurate clip information
  SkCanvas::onClipRRect(rrect, op, style);
}

void MockCanvas::onClipPath(const SkPath& path,
                            SkClipOp op,
                            ClipEdgeStyle style) {
  draw_calls_.emplace_back(
      DrawCall{current_layer_, ClipPathData{path, op, style}});
  // quickReject() is handled by base class and needs accurate clip information
  SkCanvas::onClipPath(path, op, style);
}

bool MockCanvas::onDoSaveBehind(const SkRect*) {
  FML_DCHECK(false);
  return false;
}

void MockCanvas::onDrawAnnotation(const SkRect&, const char[], SkData*) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawDrawable(SkDrawable*, const SkMatrix*) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawPatch(const SkPoint[12],
                             const SkColor[4],
                             const SkPoint[4],
                             SkBlendMode,
                             const SkPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawPaint(const SkPaint& skPaint) {
  draw_calls_.emplace_back(DrawCall{current_layer_, DrawPaint{skPaint}});
}

void MockCanvas::onDrawBehind(const SkPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawPoints(PointMode,
                              size_t,
                              const SkPoint[],
                              const SkPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawRegion(const SkRegion&, const SkPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawOval(const SkRect&, const SkPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawArc(const SkRect&,
                           SkScalar,
                           SkScalar,
                           bool,
                           const SkPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawRRect(const SkRRect&, const SkPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawImage(const SkImage*,
                             SkScalar,
                             SkScalar,
                             const SkPaint*) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawImageRect(const SkImage*,
                                 const SkRect*,
                                 const SkRect&,
                                 const SkPaint*,
                                 SrcRectConstraint) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawImageNine(const SkImage*,
                                 const SkIRect&,
                                 const SkRect&,
                                 const SkPaint*) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawImageLattice(const SkImage*,
                                    const Lattice&,
                                    const SkRect&,
                                    const SkPaint*) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawVerticesObject(const SkVertices*,
                                      SkBlendMode,
                                      const SkPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawAtlas(const SkImage*,
                             const SkRSXform[],
                             const SkRect[],
                             const SkColor[],
                             int,
                             SkBlendMode,
                             const SkRect*,
                             const SkPaint*) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawEdgeAAQuad(const SkRect&,
                                  const SkPoint[4],
                                  QuadAAFlags,
                                  const SkColor4f&,
                                  SkBlendMode) {
  FML_DCHECK(false);
}

void MockCanvas::onDrawEdgeAAImageSet(const ImageSetEntry[],
                                      int,
                                      const SkPoint[],
                                      const SkMatrix[],
                                      const SkPaint*,
                                      SrcRectConstraint) {
  FML_DCHECK(false);
}

void MockCanvas::onClipRegion(const SkRegion&, SkClipOp) {
  FML_DCHECK(false);
}

bool operator==(const MockCanvas::SaveData& a, const MockCanvas::SaveData& b) {
  return a.save_to_layer == b.save_to_layer;
}

std::ostream& operator<<(std::ostream& os, const MockCanvas::SaveData& data) {
  return os << data.save_to_layer;
}

bool operator==(const MockCanvas::SaveLayerData& a,
                const MockCanvas::SaveLayerData& b) {
  return a.save_bounds == b.save_bounds && a.restore_paint == b.restore_paint &&
         a.backdrop_filter == b.backdrop_filter &&
         a.save_to_layer == b.save_to_layer;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::SaveLayerData& data) {
  return os << data.save_bounds << " " << data.restore_paint << " "
            << data.backdrop_filter << " " << data.save_to_layer;
}

bool operator==(const MockCanvas::RestoreData& a,
                const MockCanvas::RestoreData& b) {
  return a.restore_to_layer == b.restore_to_layer;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::RestoreData& data) {
  return os << data.restore_to_layer;
}

bool operator==(const MockCanvas::ConcatMatrixData& a,
                const MockCanvas::ConcatMatrixData& b) {
  return a.matrix == b.matrix;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::ConcatMatrixData& data) {
  return os << data.matrix;
}

bool operator==(const MockCanvas::SetMatrixData& a,
                const MockCanvas::SetMatrixData& b) {
  return a.matrix == b.matrix;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::SetMatrixData& data) {
  return os << data.matrix;
}

bool operator==(const MockCanvas::DrawRectData& a,
                const MockCanvas::DrawRectData& b) {
  return a.rect == b.rect && a.paint == b.paint;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::DrawRectData& data) {
  return os << data.rect << " " << data.paint;
}

bool operator==(const MockCanvas::DrawPathData& a,
                const MockCanvas::DrawPathData& b) {
  return a.path == b.path && a.paint == b.paint;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::DrawPathData& data) {
  return os << data.path << " " << data.paint;
}

bool operator==(const MockCanvas::DrawTextData& a,
                const MockCanvas::DrawTextData& b) {
  return a.serialized_text->equals(b.serialized_text.get()) &&
         a.paint == b.paint && a.offset == b.offset;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::DrawTextData& data) {
  return os << data.serialized_text << " " << data.paint << " " << data.offset;
}

bool operator==(const MockCanvas::DrawPictureData& a,
                const MockCanvas::DrawPictureData& b) {
  return a.serialized_picture->equals(b.serialized_picture.get()) &&
         a.paint == b.paint && a.matrix == b.matrix;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::DrawPictureData& data) {
  return os << data.serialized_picture << " " << data.paint << " "
            << data.matrix;
}

bool operator==(const MockCanvas::DrawShadowData& a,
                const MockCanvas::DrawShadowData& b) {
  return a.path == b.path;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::DrawShadowData& data) {
  return os << data.path;
}

bool operator==(const MockCanvas::ClipRectData& a,
                const MockCanvas::ClipRectData& b) {
  return a.rect == b.rect && a.clip_op == b.clip_op && a.style == b.style;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::ClipRectData& data) {
  return os << data.rect << " " << data.clip_op << " " << data.style;
}

bool operator==(const MockCanvas::ClipRRectData& a,
                const MockCanvas::ClipRRectData& b) {
  return a.rrect == b.rrect && a.clip_op == b.clip_op && a.style == b.style;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::ClipRRectData& data) {
  return os << data.rrect << " " << data.clip_op << " " << data.style;
}

bool operator==(const MockCanvas::ClipPathData& a,
                const MockCanvas::ClipPathData& b) {
  return a.path == b.path && a.clip_op == b.clip_op && a.style == b.style;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::ClipPathData& data) {
  return os << data.path << " " << data.clip_op << " " << data.style;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::DrawCallData& data) {
  std::visit([&os](auto& d) { os << d; }, data);
  return os;
}

bool operator==(const MockCanvas::DrawCall& a, const MockCanvas::DrawCall& b) {
  return a.layer == b.layer && a.data == b.data;
}

std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawCall& draw) {
  return os << "[Layer: " << draw.layer << ", Data: " << draw.data << "]";
}

bool operator==(const MockCanvas::DrawPaint& a,
                const MockCanvas::DrawPaint& b) {
  return a.paint == b.paint;
}

std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawPaint& data) {
  return os << data.paint;
}

}  // namespace testing
}  // namespace flutter
