// Copyright 2016 The Chromium 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 "content/shell/test_runner/pixel_dump.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "cc/paint/paint_flags.h"
#include "cc/paint/skia_paint_canvas.h"
#include "content/shell/common/web_test/web_test_utils.h"
#include "content/shell/test_runner/web_test_runtime_flags.h"
#include "services/service_manager/public/cpp/connector.h"
// FIXME: Including platform_canvas.h here is a layering violation.
#include "skia/ext/platform_canvas.h"
#include "third_party/blink/public/mojom/clipboard/clipboard.mojom.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_image.h"
#include "third_party/blink/public/platform/web_point.h"
#include "third_party/blink/public/web/web_frame.h"
#include "third_party/blink/public/web/web_frame_widget.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_page_popup.h"
#include "third_party/blink/public/web/web_print_params.h"
#include "third_party/blink/public/web/web_view.h"
#include "third_party/blink/public/web/web_widget.h"
#include "ui/gfx/geometry/point.h"

namespace test_runner {

namespace {

class CaptureCallback : public base::RefCountedThreadSafe<CaptureCallback> {
 public:
  explicit CaptureCallback(base::OnceCallback<void(const SkBitmap&)> callback);

  void set_wait_for_popup(bool wait) { wait_for_popup_ = wait; }
  void set_popup_position(const gfx::Point& position) {
    popup_position_ = position;
  }

  void DidCompositeAndReadback(const SkBitmap& bitmap);

 private:
  friend class base::RefCountedThreadSafe<CaptureCallback>;
  ~CaptureCallback();

  base::OnceCallback<void(const SkBitmap&)> callback_;
  SkBitmap main_bitmap_;
  bool wait_for_popup_;
  gfx::Point popup_position_;
};

void DrawSelectionRect(
    const blink::WebRect& wr,
    base::OnceCallback<void(const SkBitmap&)> original_callback,
    const SkBitmap& bitmap) {
  content::web_test_utils::DrawSelectionRect(bitmap, wr);
  std::move(original_callback).Run(bitmap);
}

void CapturePixelsForPrinting(
    blink::WebLocalFrame* web_frame,
    base::OnceCallback<void(const SkBitmap&)> callback) {
  auto* frame_widget = web_frame->LocalRoot()->FrameWidget();
  frame_widget->UpdateAllLifecyclePhases(
      blink::WebWidget::LifecycleUpdateReason::kTest);

  blink::WebSize page_size_in_pixels = frame_widget->Size();

  int page_count = web_frame->PrintBegin(page_size_in_pixels);
  int totalHeight = page_count * (page_size_in_pixels.height + 1) - 1;

  bool is_opaque = false;

  SkBitmap bitmap;
  if (!bitmap.tryAllocN32Pixels(page_size_in_pixels.width, totalHeight,
                                is_opaque)) {
    LOG(ERROR) << "Failed to create bitmap width=" << page_size_in_pixels.width
               << " height=" << totalHeight;
    std::move(callback).Run(SkBitmap());
    return;
  }

  cc::SkiaPaintCanvas canvas(bitmap);
  web_frame->PrintPagesForTesting(&canvas, page_size_in_pixels);
  web_frame->PrintEnd();

  std::move(callback).Run(bitmap);
}

CaptureCallback::CaptureCallback(
    base::OnceCallback<void(const SkBitmap&)> callback)
    : callback_(std::move(callback)), wait_for_popup_(false) {}

CaptureCallback::~CaptureCallback() {}

void CaptureCallback::DidCompositeAndReadback(const SkBitmap& bitmap) {
  TRACE_EVENT2("shell", "CaptureCallback::didCompositeAndReadback", "x",
               bitmap.info().width(), "y", bitmap.info().height());
  if (!wait_for_popup_) {
    std::move(callback_).Run(bitmap);
    return;
  }
  if (main_bitmap_.isNull()) {
    if (main_bitmap_.tryAllocPixels(bitmap.info())) {
      bitmap.readPixels(main_bitmap_.info(), main_bitmap_.getPixels(),
                        main_bitmap_.rowBytes(), 0, 0);
    }
    return;
  }
  SkCanvas canvas(main_bitmap_);
  canvas.drawBitmap(bitmap, popup_position_.x(), popup_position_.y());
  std::move(callback_).Run(main_bitmap_);
}

}  // namespace

void DumpPixelsAsync(blink::WebLocalFrame* web_frame,
                     float device_scale_factor_for_test,
                     base::OnceCallback<void(const SkBitmap&)> callback) {
  DCHECK(web_frame);
  DCHECK_LT(0.0, device_scale_factor_for_test);
  DCHECK(!callback.is_null());

  blink::WebWidget* web_widget = web_frame->FrameWidget();
  auto capture_callback =
      base::MakeRefCounted<CaptureCallback>(std::move(callback));
  auto did_readback = base::BindRepeating(
      &CaptureCallback::DidCompositeAndReadback, capture_callback);
  web_widget->CompositeAndReadbackAsync(did_readback);
  // The current PagePopup is composited together with the main frame.
  if (!web_frame->Parent()) {
    if (blink::WebPagePopup* popup = web_frame->View()->GetPagePopup()) {
      capture_callback->set_wait_for_popup(true);
      blink::WebPoint position = popup->PositionRelativeToOwner();
      position.x *= device_scale_factor_for_test;
      position.y *= device_scale_factor_for_test;
      capture_callback->set_popup_position(position);
      popup->CompositeAndReadbackAsync(did_readback);
    }
  }
}

void PrintFrameAsync(blink::WebLocalFrame* web_frame,
                     base::OnceCallback<void(const SkBitmap&)> callback) {
  DCHECK(web_frame);
  DCHECK(!callback.is_null());
  web_frame->GetTaskRunner(blink::TaskType::kInternalTest)
      ->PostTask(FROM_HERE, base::BindOnce(&CapturePixelsForPrinting,
                                           base::Unretained(web_frame),
                                           std::move(callback)));
}

base::OnceCallback<void(const SkBitmap&)>
CreateSelectionBoundsRectDrawingCallback(
    blink::WebLocalFrame* web_frame,
    base::OnceCallback<void(const SkBitmap&)> original_callback) {
  DCHECK(web_frame);
  DCHECK(!original_callback.is_null());

  // If there is no selection rect, just return the original callback.
  blink::WebRect wr = web_frame->GetSelectionBoundsRectForTesting();
  if (wr.IsEmpty())
    return original_callback;

  return base::BindOnce(&DrawSelectionRect, wr, std::move(original_callback));
}

void CopyImageAtAndCapturePixels(
    blink::WebLocalFrame* web_frame,
    int x,
    int y,
    base::OnceCallback<void(const SkBitmap&)> callback) {
  blink::mojom::ClipboardHostPtr clipboard;
  blink::Platform::Current()->GetConnector()->BindInterface(
      blink::Platform::Current()->GetBrowserServiceName(), &clipboard);

  uint64_t sequence_number_before = 0;
  clipboard->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE,
                               &sequence_number_before);
  web_frame->CopyImageAt(blink::WebPoint(x, y));
  uint64_t sequence_number_after = 0;
  while (sequence_number_before == sequence_number_after) {
    clipboard->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE,
                                 &sequence_number_after);
  }

  SkBitmap bitmap;
  clipboard->ReadImage(ui::CLIPBOARD_TYPE_COPY_PASTE, &bitmap);
  std::move(callback).Run(bitmap);
}

}  // namespace test_runner
