// 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 "flutter/testing/display_list_testing.h"
#include "third_party/skia/include/core/SkImageInfo.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()
    : tracker_(SkRect::Make(kSize), SkMatrix::I()), current_layer_(0) {}

MockCanvas::MockCanvas(int width, int height)
    : tracker_(SkRect::MakeIWH(width, height), SkMatrix::I()),
      current_layer_(0) {}

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

SkISize MockCanvas::GetBaseLayerSize() const {
  return tracker_.base_device_cull_rect().roundOut().size();
}

SkImageInfo MockCanvas::GetImageInfo() const {
  SkISize size = GetBaseLayerSize();
  return SkImageInfo::MakeUnknown(size.width(), size.height());
}

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

void MockCanvas::SaveLayer(const SkRect* bounds,
                           const DlPaint* paint,
                           const DlImageFilter* backdrop) {
  // saveLayer calls this prior to running, so we use it to track saveLayer
  // calls
  draw_calls_.emplace_back(DrawCall{
      current_layer_,
      SaveLayerData{bounds ? *bounds : SkRect(), paint ? *paint : DlPaint(),
                    backdrop ? backdrop->shared() : nullptr,
                    current_layer_ + 1}});
  tracker_.save();
  current_layer_++;  // Must go here; func params order of eval is undefined
}

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

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

// clang-format off

// 2x3 2D affine subset of a 4x4 transform in row major order
void MockCanvas::Transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt,
                                   SkScalar myx, SkScalar myy, SkScalar myt) {
  Transform(SkMatrix::MakeAll(mxx, mxy, mxt, myx, myy, myt, 0, 0, 1));
}

// full 4x4 transform in row major order
void MockCanvas::TransformFullPerspective(
    SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
    SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
    SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
    SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
  Transform(SkM44(mxx, mxy, mxz, mxt,
                  myx, myy, myz, myt,
                  mzx, mzy, mzz, mzt,
                  mwx, mwy, mwz, mwt));
}

// clang-format on

void MockCanvas::Transform(const SkMatrix* matrix) {
  draw_calls_.emplace_back(
      DrawCall{current_layer_, ConcatMatrixData{SkM44(*matrix)}});
  tracker_.transform(*matrix);
}

void MockCanvas::Transform(const SkM44* matrix) {
  draw_calls_.emplace_back(DrawCall{current_layer_, ConcatMatrixData{*matrix}});
  tracker_.transform(*matrix);
}

void MockCanvas::SetTransform(const SkMatrix* matrix) {
  draw_calls_.emplace_back(
      DrawCall{current_layer_, SetMatrixData{SkM44(*matrix)}});
  tracker_.setTransform(*matrix);
}

void MockCanvas::SetTransform(const SkM44* matrix) {
  draw_calls_.emplace_back(DrawCall{current_layer_, SetMatrixData{*matrix}});
  tracker_.setTransform(*matrix);
}

void MockCanvas::TransformReset() {
  draw_calls_.emplace_back(DrawCall{current_layer_, SetMatrixData{SkM44()}});
  tracker_.setIdentity();
}

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

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

void MockCanvas::Rotate(SkScalar degrees) {
  this->Transform(SkMatrix::RotateDeg(degrees));
}

void MockCanvas::Skew(SkScalar sx, SkScalar sy) {
  this->Transform(SkMatrix::Skew(sx, sy));
}

SkM44 MockCanvas::GetTransformFullPerspective() const {
  return tracker_.matrix_4x4();
}

SkMatrix MockCanvas::GetTransform() const {
  return tracker_.matrix_3x3();
}

void MockCanvas::DrawTextBlob(const sk_sp<SkTextBlob>& text,
                              SkScalar x,
                              SkScalar y,
                              const DlPaint& 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;
  // if (paint.canComputeFastBounds()) {
  //   storage = text->bounds().makeOffset(x, y);
  //   SkRect tmp;
  //   if (this->quickReject(paint.computeFastBounds(storage, &tmp))) {
  //     return;
  //   }
  // }

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

void MockCanvas::DrawTextFrame(
    const std::shared_ptr<impeller::TextFrame>& text_frame,
    SkScalar x,
    SkScalar y,
    const DlPaint& paint) {
  FML_DCHECK(false);
}

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

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

void MockCanvas::DrawShadow(const SkPath& path,
                            const DlColor color,
                            const SkScalar elevation,
                            bool transparent_occluder,
                            SkScalar dpr) {
  draw_calls_.emplace_back(DrawCall{
      current_layer_,
      DrawShadowData{path, color, elevation, transparent_occluder, dpr}});
}

void MockCanvas::DrawImage(const sk_sp<DlImage>& image,
                           SkPoint point,
                           const DlImageSampling options,
                           const DlPaint* paint) {
  if (paint) {
    draw_calls_.emplace_back(
        DrawCall{current_layer_,
                 DrawImageData{image, point.fX, point.fY, options, *paint}});
  } else {
    draw_calls_.emplace_back(
        DrawCall{current_layer_,
                 DrawImageDataNoPaint{image, point.fX, point.fY, options}});
  }
}

void MockCanvas::DrawDisplayList(const sk_sp<DisplayList> display_list,
                                 SkScalar opacity) {
  draw_calls_.emplace_back(
      DrawCall{current_layer_, DrawDisplayListData{display_list, opacity}});
}

void MockCanvas::ClipRect(const SkRect& rect, ClipOp op, bool is_aa) {
  ClipEdgeStyle style = is_aa ? kSoftClipEdgeStyle : kHardClipEdgeStyle;
  draw_calls_.emplace_back(
      DrawCall{current_layer_, ClipRectData{rect, op, style}});
  tracker_.clipRect(rect, op, is_aa);
}

void MockCanvas::ClipRRect(const SkRRect& rrect, ClipOp op, bool is_aa) {
  ClipEdgeStyle style = is_aa ? kSoftClipEdgeStyle : kHardClipEdgeStyle;
  draw_calls_.emplace_back(
      DrawCall{current_layer_, ClipRRectData{rrect, op, style}});
  tracker_.clipRRect(rrect, op, is_aa);
}

void MockCanvas::ClipPath(const SkPath& path, ClipOp op, bool is_aa) {
  ClipEdgeStyle style = is_aa ? kSoftClipEdgeStyle : kHardClipEdgeStyle;
  draw_calls_.emplace_back(
      DrawCall{current_layer_, ClipPathData{path, op, style}});
  tracker_.clipPath(path, op, is_aa);
}

SkRect MockCanvas::GetDestinationClipBounds() const {
  return tracker_.device_cull_rect();
}

SkRect MockCanvas::GetLocalClipBounds() const {
  return tracker_.local_cull_rect();
}

bool MockCanvas::QuickReject(const SkRect& bounds) const {
  return tracker_.content_culled(bounds);
}

void MockCanvas::DrawDRRect(const SkRRect&, const SkRRect&, const DlPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::DrawPaint(const DlPaint& paint) {
  draw_calls_.emplace_back(DrawCall{current_layer_, DrawPaintData{paint}});
}

void MockCanvas::DrawColor(DlColor color, DlBlendMode mode) {
  DrawPaint(DlPaint(color).setBlendMode(mode));
}

void MockCanvas::DrawLine(const SkPoint& p0,
                          const SkPoint& p1,
                          const DlPaint& paint) {
  FML_DCHECK(false);
}

void MockCanvas::DrawPoints(PointMode,
                            uint32_t,
                            const SkPoint[],
                            const DlPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::DrawOval(const SkRect&, const DlPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::DrawCircle(const SkPoint& center,
                            SkScalar radius,
                            const DlPaint& paint) {
  FML_DCHECK(false);
}

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

void MockCanvas::DrawRRect(const SkRRect&, const DlPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::DrawImageRect(const sk_sp<DlImage>&,
                               const SkRect&,
                               const SkRect&,
                               const DlImageSampling,
                               const DlPaint*,
                               SrcRectConstraint constraint) {
  FML_DCHECK(false);
}

void MockCanvas::DrawImageNine(const sk_sp<DlImage>& image,
                               const SkIRect& center,
                               const SkRect& dst,
                               DlFilterMode filter,
                               const DlPaint* paint) {
  FML_DCHECK(false);
}

void MockCanvas::DrawVertices(const DlVertices*, DlBlendMode, const DlPaint&) {
  FML_DCHECK(false);
}

void MockCanvas::DrawAtlas(const sk_sp<DlImage>&,
                           const SkRSXform[],
                           const SkRect[],
                           const DlColor[],
                           int,
                           DlBlendMode,
                           const DlImageSampling,
                           const SkRect*,
                           const DlPaint*) {
  FML_DCHECK(false);
}

void MockCanvas::Flush() {
  FML_DCHECK(false);
}

// --------------------------------------------------------
// A few ostream operators duplicated from assertions_skia.cc
// In the short term, there are issues trying to include that file
// here because it appears in a skia-targeted testing source set
// and in the long term, DlCanvas, and therefore this file will
// eventually be cleaned of these SkObject dependencies and these
// ostream operators will be converted to their DL equivalents.
static std::ostream& operator<<(std::ostream& os, const SkPoint& r) {
  return os << "XY: " << r.fX << ", " << r.fY;
}

static std::ostream& operator<<(std::ostream& os, const SkRect& r) {
  return os << "LTRB: " << r.fLeft << ", " << r.fTop << ", " << r.fRight << ", "
            << r.fBottom;
}

static std::ostream& operator<<(std::ostream& os, const SkRRect& r) {
  return os << "LTRB: " << r.rect().fLeft << ", " << r.rect().fTop << ", "
            << r.rect().fRight << ", " << r.rect().fBottom;
}

static std::ostream& operator<<(std::ostream& os, const SkPath& r) {
  return os << "Valid: " << r.isValid()
            << ", FillType: " << static_cast<int>(r.getFillType())
            << ", Bounds: " << r.getBounds();
}
// --------------------------------------------------------

static std::ostream& operator<<(std::ostream& os, const SkM44& m) {
  os << m.rc(0, 0) << ", " << m.rc(0, 1) << ", " << m.rc(0, 2) << ", "
     << m.rc(0, 3) << std::endl;
  os << m.rc(1, 0) << ", " << m.rc(1, 1) << ", " << m.rc(1, 2) << ", "
     << m.rc(1, 3) << std::endl;
  os << m.rc(2, 0) << ", " << m.rc(2, 1) << ", " << m.rc(2, 2) << ", "
     << m.rc(2, 3) << std::endl;
  os << m.rc(3, 0) << ", " << m.rc(3, 1) << ", " << m.rc(3, 2) << ", "
     << m.rc(3, 3);
  return os;
}

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 &&
         Equals(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::DrawImageData& a,
                const MockCanvas::DrawImageData& b) {
  return a.image == b.image && a.x == b.x && a.y == b.y &&
         a.options == b.options && a.paint == b.paint;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::DrawImageData& data) {
  return os << data.image << " " << data.x << " " << data.y << " "
            << data.options << " " << data.paint;
}

bool operator==(const MockCanvas::DrawImageDataNoPaint& a,
                const MockCanvas::DrawImageDataNoPaint& b) {
  return a.image == b.image && a.x == b.x && a.y == b.y &&
         a.options == b.options;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::DrawImageDataNoPaint& data) {
  return os << data.image << " " << data.x << " " << data.y << " "
            << data.options;
}

bool operator==(const MockCanvas::DrawDisplayListData& a,
                const MockCanvas::DrawDisplayListData& b) {
  return a.display_list->Equals(b.display_list) && a.opacity == b.opacity;
}

std::ostream& operator<<(std::ostream& os,
                         const MockCanvas::DrawDisplayListData& data) {
  auto dl = data.display_list;
  return os << "[" << dl->unique_id() << " " << dl->op_count() << " "
            << dl->bytes() << "] " << data.opacity;
}

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

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

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;
}

static std::ostream& operator<<(std::ostream& os,
                                const MockCanvas::ClipEdgeStyle& style) {
  return os << (style == MockCanvas::kSoftClipEdgeStyle ? "kSoftEdges"
                                                        : "kHardEdges");
}

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::DrawPaintData& a,
                const MockCanvas::DrawPaintData& b) {
  return a.paint == b.paint;
}

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

}  // namespace testing
}  // namespace flutter
