// Copyright 2019 PDFium 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 <utility>

#include "build/build_config.h"
#include "core/fxcrt/fx_system.h"
#include "public/fpdf_progressive.h"
#include "testing/embedder_test.h"
#include "testing/gtest/include/gtest/gtest.h"

class FPDFProgressiveRenderEmbedderTest : public EmbedderTest {
 public:
  // StartRenderPageWithFlags() with no flags.
  // The call returns true if the rendering is complete.
  bool StartRenderPage(FPDF_PAGE page, IFSDK_PAUSE* pause);

  // Start rendering of |page| into a bitmap with the ability to pause the
  // rendering with the specified rendering |flags|.
  // The call returns true if the rendering is complete.
  //
  // See public/fpdfview.h for a list of page rendering flags.
  bool StartRenderPageWithFlags(FPDF_PAGE page, IFSDK_PAUSE* pause, int flags);

  // Continue rendering of |page| into the bitmap created in
  // StartRenderPageWithFlags().
  // The call returns true if the rendering is complete.
  bool ContinueRenderPage(FPDF_PAGE page, IFSDK_PAUSE* pause);

  // Simplified form of FinishRenderPageWithForms() with no form handle.
  ScopedFPDFBitmap FinishRenderPage(FPDF_PAGE page);

  // Finish rendering of |page| into the bitmap created in
  // StartRenderPageWithFlags(). This also renders the forms associated with
  // the page. The form handle associated with |page| should be passed in via
  // |handle|. If |handle| is nullptr, then forms on the page will not be
  // rendered.
  // This returns the bitmap generated by the progressive render calls.
  ScopedFPDFBitmap FinishRenderPageWithForms(FPDF_PAGE page,
                                             FPDF_FORMHANDLE handle);

 private:
  // Keeps the bitmap used for progressive rendering alive until
  // FPDF_RenderPage_Close() is called after which the bitmap is returned
  // to the caller.
  ScopedFPDFBitmap progressive_render_bitmap_;
  int progressive_render_flags_ = 0;
};

bool FPDFProgressiveRenderEmbedderTest::StartRenderPage(FPDF_PAGE page,
                                                        IFSDK_PAUSE* pause) {
  return StartRenderPageWithFlags(page, pause, 0);
}

bool FPDFProgressiveRenderEmbedderTest::StartRenderPageWithFlags(
    FPDF_PAGE page,
    IFSDK_PAUSE* pause,
    int flags) {
  int width = static_cast<int>(FPDF_GetPageWidth(page));
  int height = static_cast<int>(FPDF_GetPageHeight(page));
  progressive_render_flags_ = flags;
  int alpha = FPDFPage_HasTransparency(page) ? 1 : 0;
  progressive_render_bitmap_ =
      ScopedFPDFBitmap(FPDFBitmap_Create(width, height, alpha));
  FPDF_DWORD fill_color = alpha ? 0x00000000 : 0xFFFFFFFF;
  FPDFBitmap_FillRect(progressive_render_bitmap_.get(), 0, 0, width, height,
                      fill_color);
  int rv = FPDF_RenderPageBitmap_Start(progressive_render_bitmap_.get(), page,
                                       0, 0, width, height, 0,
                                       progressive_render_flags_, pause);
  return rv != FPDF_RENDER_TOBECONTINUED;
}

bool FPDFProgressiveRenderEmbedderTest::ContinueRenderPage(FPDF_PAGE page,
                                                           IFSDK_PAUSE* pause) {
  ASSERT(progressive_render_bitmap_);

  int rv = FPDF_RenderPage_Continue(page, pause);
  return rv != FPDF_RENDER_TOBECONTINUED;
}

ScopedFPDFBitmap FPDFProgressiveRenderEmbedderTest::FinishRenderPage(
    FPDF_PAGE page) {
  return FinishRenderPageWithForms(page, /*handle=*/nullptr);
}

ScopedFPDFBitmap FPDFProgressiveRenderEmbedderTest::FinishRenderPageWithForms(
    FPDF_PAGE page,
    FPDF_FORMHANDLE handle) {
  ASSERT(progressive_render_bitmap_);

  int width = static_cast<int>(FPDF_GetPageWidth(page));
  int height = static_cast<int>(FPDF_GetPageHeight(page));
  FPDF_FFLDraw(handle, progressive_render_bitmap_.get(), page, 0, 0, width,
               height, 0, progressive_render_flags_);
  FPDF_RenderPage_Close(page);
  return std::move(progressive_render_bitmap_);
}

class FakePause : public IFSDK_PAUSE {
 public:
  explicit FakePause(bool should_pause) : should_pause_(should_pause) {
    IFSDK_PAUSE::version = 1;
    IFSDK_PAUSE::user = nullptr;
    IFSDK_PAUSE::NeedToPauseNow = Pause_NeedToPauseNow;
  }
  ~FakePause() = default;

  static FPDF_BOOL Pause_NeedToPauseNow(IFSDK_PAUSE* param) {
    return static_cast<FakePause*>(param)->should_pause_;
  }

 private:
  const bool should_pause_ = false;
};

TEST_F(FPDFProgressiveRenderEmbedderTest, RenderWithoutPause) {
#if defined(OS_WIN)
  static constexpr char kMd5BaseContent[] = "649d6792ea50faf98c013c2d81710595";
#elif defined(OS_MACOSX)
  static constexpr char kMd5BaseContent[] = "5f933aac2a74434be1b4d0bdb5334f0b";
#else
  static constexpr char kMd5BaseContent[] = "a24edc7740f1d6f76899652dcf825dea";
#endif

  // Test rendering of page content using progressive render APIs
  // without pausing the rendering.
  EXPECT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
  FPDF_PAGE page = LoadPage(0);
  ASSERT_TRUE(page);
  FakePause pause(false);
  EXPECT_TRUE(StartRenderPage(page, &pause));
  ScopedFPDFBitmap bitmap = FinishRenderPage(page);
  CompareBitmap(bitmap.get(), 595, 842, kMd5BaseContent);
  UnloadPage(page);
}

TEST_F(FPDFProgressiveRenderEmbedderTest, RenderWithPause) {
#if defined(OS_WIN)
  static constexpr char kMd5BaseContent[] = "649d6792ea50faf98c013c2d81710595";
#elif defined(OS_MACOSX)
  static constexpr char kMd5BaseContent[] = "5f933aac2a74434be1b4d0bdb5334f0b";
#else
  static constexpr char kMd5BaseContent[] = "a24edc7740f1d6f76899652dcf825dea";
#endif

  // Test rendering of page content using progressive render APIs
  // with pause in rendering.
  EXPECT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
  FPDF_PAGE page = LoadPage(0);
  ASSERT_TRUE(page);
  FakePause pause(true);
  bool render_done = StartRenderPage(page, &pause);
  EXPECT_FALSE(render_done);

  while (!render_done) {
    render_done = ContinueRenderPage(page, &pause);
  }
  ScopedFPDFBitmap bitmap = FinishRenderPage(page);
  CompareBitmap(bitmap.get(), 595, 842, kMd5BaseContent);
  UnloadPage(page);
}

TEST_F(FPDFProgressiveRenderEmbedderTest, RenderAnnotWithPause) {
#if defined(OS_WIN)
  static constexpr char kMd5ContentWithAnnot[] =
      "6aa001a77ec05d0f1b0d1d22e28744d4";
#elif defined(OS_MACOSX)
  static constexpr char kMd5ContentWithAnnot[] =
      "c35408717759562d1f8bf33d317483d2";
#else
  static constexpr char kMd5ContentWithAnnot[] =
      "b42cef463483e668eaf4055a65e4f1f5";
#endif

  // Test rendering of the page with annotations using progressive render APIs
  // with pause in rendering.
  EXPECT_TRUE(OpenDocument("annotation_stamp_with_ap.pdf"));
  FPDF_PAGE page = LoadPage(0);
  ASSERT_TRUE(page);
  FakePause pause(true);
  bool render_done = StartRenderPageWithFlags(page, &pause, FPDF_ANNOT);
  EXPECT_FALSE(render_done);

  while (!render_done) {
    render_done = ContinueRenderPage(page, &pause);
  }
  ScopedFPDFBitmap bitmap = FinishRenderPage(page);
  CompareBitmap(bitmap.get(), 595, 842, kMd5ContentWithAnnot);
  UnloadPage(page);
}

TEST_F(FPDFProgressiveRenderEmbedderTest, RenderFormsWithPause) {
#if defined(OS_WIN)
  static constexpr char kMd5ContentWithForms[] =
      "d3204faa62b607f0bd3893c9c22cabcb";
#elif defined(OS_MACOSX)
  static constexpr char kMd5ContentWithForms[] =
      "5f11dbe575fe197a37c3fb422559f8ff";
#else
  static constexpr char kMd5ContentWithForms[] =
      "b890950d4b9bc163b1a96797f3004b53";
#endif

  // Test rendering of the page with forms using progressive render APIs
  // with pause in rendering.
  EXPECT_TRUE(OpenDocument("text_form.pdf"));
  FPDF_PAGE page = LoadPage(0);
  ASSERT_TRUE(page);
  FakePause pause(true);
  bool render_done = StartRenderPage(page, &pause);
  EXPECT_FALSE(render_done);

  while (!render_done) {
    render_done = ContinueRenderPage(page, &pause);
  }
  ScopedFPDFBitmap bitmap = FinishRenderPageWithForms(page, form_handle_);
  CompareBitmap(bitmap.get(), 300, 300, kMd5ContentWithForms);
  UnloadPage(page);
}
