// Copyright 2015 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef TESTING_EMBEDDER_TEST_H_
#define TESTING_EMBEDDER_TEST_H_

#include <stdint.h>

#include <concepts>
#include <fstream>
#include <map>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "build/build_config.h"
#include "core/fxcrt/bytestring.h"
#include "core/fxcrt/check.h"
#include "core/fxcrt/span.h"
#include "core/fxcrt/unowned_ptr.h"
#include "public/cpp/fpdf_scopers.h"
#include "public/fpdf_dataavail.h"
#include "public/fpdf_ext.h"
#include "public/fpdf_formfill.h"
#include "public/fpdf_save.h"
#include "public/fpdfview.h"
#include "testing/fake_file_access.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/utils/pixel_diff_util.h"

class TestLoader;

// The loading time of the CFGAS_FontMgr is linear in the number of times it is
// loaded. So, if a test suite has a lot of tests that need a font manager they
// can end up executing very, very slowly.

// Helper macro for common equality assertions with a fixed tolerance of 0.001.
#define EXPECT_NEAR_THREE_PLACES(a, b) EXPECT_NEAR((a), (b), 0.001)

// This class is used to load a PDF document, and then run programatic
// API tests against it.
class EmbedderTest : public ::testing::Test,
                     public UNSUPPORT_INFO,
                     public IPDF_JSPLATFORM,
                     public FPDF_FORMFILLINFO,
                     public FPDF_FILEWRITE {
 public:
  enum class LinearizeOption { kDefaultLinearize, kMustLinearize };
  enum class JavaScriptOption { kDisableJavaScript, kEnableJavaScript };

  class Delegate {
   public:
    virtual ~Delegate() = default;

    // Equivalent to UNSUPPORT_INFO::FSDK_UnSupport_Handler().
    virtual void UnsupportedHandler(int type) {}

    // Equivalent to IPDF_JSPLATFORM::app_alert().
    virtual int Alert(FPDF_WIDESTRING message,
                      FPDF_WIDESTRING title,
                      int type,
                      int icon) {
      return 0;
    }

    // Equivalent to FPDF_FORMFILLINFO::FFI_SetTimer().
    virtual int SetTimer(int msecs, TimerCallback fn) { return 0; }

    // Equivalent to FPDF_FORMFILLINFO::FFI_KillTimer().
    virtual void KillTimer(int id) {}

    // Equivalent to FPDF_FORMFILLINFO::FFI_GetPage().
    virtual FPDF_PAGE GetPage(FPDF_FORMFILLINFO* info,
                              FPDF_DOCUMENT document,
                              int page_index);

    // Equivalent to FPDF_FORMFILLINFO::FFI_DoURIAction().
    virtual void DoURIAction(FPDF_BYTESTRING uri) {}

    // Equivalent to FPDF_FORMFILLINFO::FFI_DoGoToAction().
    virtual void DoGoToAction(FPDF_FORMFILLINFO* info,
                              int page_index,
                              int zoom_mode,
                              float* pos_arry,
                              int array_size) {}

    // Equivalent to FPDF_FORMFILLINFO::FFI_OnFocusChange().
    virtual void OnFocusChange(FPDF_FORMFILLINFO* info,
                               FPDF_ANNOTATION annot,
                               int page_index) {}

    // Equivalent to FPDF_FORMFILLINFO::FFI_DoURIActionWithKeyboardModifier().
    virtual void DoURIActionWithKeyboardModifier(FPDF_FORMFILLINFO* info,
                                                 FPDF_BYTESTRING uri,
                                                 int modifiers) {}
  };

  class ScopedSavedDoc {
   public:
    ScopedSavedDoc();
    explicit ScopedSavedDoc(EmbedderTest* test);
    ScopedSavedDoc(EmbedderTest* test, const ByteString& password);
    ScopedSavedDoc(const ScopedSavedDoc&) = delete;
    ScopedSavedDoc& operator=(const ScopedSavedDoc&) = delete;
    ScopedSavedDoc(ScopedSavedDoc&&) noexcept;
    ScopedSavedDoc& operator=(ScopedSavedDoc&&) noexcept;
    ~ScopedSavedDoc();

    FPDF_DOCUMENT get() { return doc_; }

    explicit operator bool() const { return !!doc_; }

   private:
    UnownedPtr<EmbedderTest> test_;
    FPDF_DOCUMENT doc_;
  };

  class ScopedPageBase {
   public:
    FPDF_PAGE get() { return page_; }

    explicit operator bool() const { return !!page_; }

   protected:
    ScopedPageBase(EmbedderTest* test, FPDF_PAGE page);
    ~ScopedPageBase();

    UnownedPtr<EmbedderTest> test_;
    FPDF_PAGE page_;
  };

  class ScopedPage : public ScopedPageBase {
   public:
    ScopedPage();
    ScopedPage(EmbedderTest* test, int page_index);
    ScopedPage(const ScopedPage&) = delete;
    ScopedPage& operator=(const ScopedPage&) = delete;
    ScopedPage(ScopedPage&&) noexcept;
    ScopedPage& operator=(ScopedPage&&) noexcept;
    ~ScopedPage();
  };

  class ScopedSavedPage : public ScopedPageBase {
   public:
    ScopedSavedPage();
    ScopedSavedPage(EmbedderTest* test, int page_index);
    ScopedSavedPage(const ScopedSavedPage&) = delete;
    ScopedSavedPage& operator=(const ScopedSavedPage&) = delete;
    ScopedSavedPage(ScopedSavedPage&&) noexcept;
    ScopedSavedPage& operator=(ScopedSavedPage&&) noexcept;
    ~ScopedSavedPage();
  };

  EmbedderTest();
  ~EmbedderTest() override;

  void SetUp() override;
  void TearDown() override;

  Delegate* GetDelegate() { return delegate_; }

  // Creates and installs a delegate owned by this fixture. The delegate stays
  // alive until TearDown() closes the document and restores the default
  // delegate. This method may only be called once per fixture.
  template <std::derived_from<Delegate> T, typename... Args>
  T& SetOwnedDelegate(Args&&... args) {
    CHECK(!owned_delegate_);
    auto delegate = std::make_unique<T>(std::forward<Args>(args)...);
    T& result = *delegate;
    owned_delegate_ = std::move(delegate);
    delegate_ = owned_delegate_.get();
    return result;
  }

  void SetFormFillInfoVersion(int form_fill_info_version) {
    form_fill_info_version_ = form_fill_info_version;
  }

  void SetDocumentFromAvail();
  FPDF_DOCUMENT document() const { return document_.get(); }
  FPDF_DOCUMENT saved_document() const { return saved_document_.get(); }
  FPDF_FORMHANDLE form_handle() const { return form_handle_.get(); }
  FPDF_FORMHANDLE saved_form_handle() const { return saved_form_handle_.get(); }

  // Wrapper for FPDFAvail_Create() to set `avail_`.
  void CreateAvail(FX_FILEAVAIL* file_avail, FPDF_FILEACCESS* file);
  FPDF_AVAIL avail() { return avail_.get(); }

  // Create an empty document, and its form fill environment.
  void CreateEmptyDocument();

  // Create an empty document without a form fill environment.
  void CreateEmptyDocumentWithoutFormFillEnvironment();

  // Open the document specified by `filename`, and create its form fill
  // environment, or return false on failure. The `filename` is relative to
  // the test data directory where we store all the test files. `password` can
  // be an empty string if the file is not password protected. If
  // `javascript_opts` is kDisableJavascript, then the document will be given
  // stubs in place of the real JS engine.
  virtual bool OpenDocumentWithOptions(const std::string& filename,
                                       const ByteString& password,
                                       LinearizeOption linearize_option,
                                       JavaScriptOption javascript_option);

  // Variants provided for convenience.
  bool OpenDocument(const std::string& filename);
  bool OpenDocumentLinearized(const std::string& filename);
  bool OpenDocumentWithPassword(const std::string& filename,
                                const ByteString& password);
  bool OpenDocumentWithoutJavaScript(const std::string& filename);

  // Close the document from a previous OpenDocument() call. This happens
  // automatically at tear-down, and is usually not explicitly required,
  // unless testing multiple documents or duplicate destruction.
  void CloseDocument();

  // Perform JavaScript actions that are to run at document open time.
  void DoOpenActions();

  // Determine the page numbers present in the document.
  int GetFirstPageNum();
  int GetPageCount();

  // Load a specific page of the open document with a given non-negative
  // `page_index`. On success, fire form events for the page and return a
  // ScopedPage with the page handle. On failure, return an empty ScopedPage.
  // The caller needs to let the ScopedPage go out of scope to properly unload
  // the page, and must do so before the page's document and `this` get
  // destroyed.
  // The caller cannot call this for a `page_index` if it already obtained and
  // holds the page handle for that page.
  ScopedPage LoadScopedPage(int page_index);

  // Prefer LoadScopedPage() above.
  //
  // Load a specific page of the open document with a given non-negative
  // `page_index`. On success, fire form events for the page and return a page
  // handle. On failure, return nullptr.
  // The caller does not own the returned page handle, but must call
  // UnloadPage() on it when done.
  // The caller cannot call this for a `page_index` if it already obtained and
  // holds the page handle for that page.
  FPDF_PAGE LoadPage(int page_index);

  // Same as LoadPage(), but does not fire form events.
  FPDF_PAGE LoadPageNoEvents(int page_index);

  // Fire form unload events and release the resources for a `page` obtained
  // from LoadPage(). Further use of `page` is prohibited after calling this.
  void UnloadPage(FPDF_PAGE page);

  // Same as UnloadPage(), but does not fire form events.
  void UnloadPageNoEvents(FPDF_PAGE page);

  // Apply standard highlighting color/alpha to forms.
  void SetInitialFormFieldHighlight(FPDF_FORMHANDLE form);

  // RenderLoadedPageWithFlags() with no flags.
  ScopedFPDFBitmap RenderLoadedPage(FPDF_PAGE page);

  // Convert `page` loaded via LoadPage() into a bitmap with the specified page
  // rendering `flags`.
  //
  // See public/fpdfview.h for a list of page rendering flags.
  ScopedFPDFBitmap RenderLoadedPageWithFlags(FPDF_PAGE page, int flags);

  // RenderSavedPageWithFlags() with no flags.
  ScopedFPDFBitmap RenderSavedPage(FPDF_PAGE page);

  // Convert `page` loaded via LoadSavedPage() into a bitmap with the specified
  // page rendering `flags`.
  //
  // See public/fpdfview.h for a list of page rendering flags.
  ScopedFPDFBitmap RenderSavedPageWithFlags(FPDF_PAGE page, int flags);

  // Convert `page` into a bitmap with the specified page rendering `flags`.
  // 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.
  //
  // See public/fpdfview.h for a list of page rendering flags.
  // If none of the above Render methods are appropriate, then use this one.
  static ScopedFPDFBitmap RenderPageWithFlags(FPDF_PAGE page,
                                              FPDF_FORMHANDLE handle,
                                              int flags);

  // Simplified form of RenderPageWithFlags() with no handle and no flags.
  static ScopedFPDFBitmap RenderPage(FPDF_PAGE page);

#if BUILDFLAG(IS_WIN)
  // Convert `page` into EMF with the specified page rendering `flags`.
  static std::vector<uint8_t> RenderPageWithFlagsToEmf(FPDF_PAGE page,
                                                       int flags);

  // Get the PostScript data from `emf_data`.
  static std::string GetPostScriptFromEmf(pdfium::span<const uint8_t> emf_data);
#endif  // BUILDFLAG(IS_WIN)

  // Return bytes for each of the FPDFBitmap_* format types.
  static int BytesPerPixelForFormat(int format);

 protected:
  using PageNumberToHandleMap = std::map<int, FPDF_PAGE>;

  bool OpenDocumentHelper(const ByteString& password,
                          LinearizeOption linearize_option,
                          JavaScriptOption javascript_option,
                          FakeFileAccess* network_simulator,
                          ScopedFPDFDocument* document,
                          ScopedFPDFAvail* avail,
                          ScopedFPDFFormHandle* form_handle);

  FPDF_FORMHANDLE SetupFormFillEnvironment(FPDF_DOCUMENT doc,
                                           JavaScriptOption javascript_option);

  // Return the hash of only the pixels in `bitmap`. i.e. Excluding the gap, if
  // any, at the end of a row where the stride is larger than width * bpp.
  static std::string HashBitmap(FPDF_BITMAP bitmap);

  // For debugging purposes.
  // Write `bitmap` as a PNG to `filename`.
  static void WriteBitmapToPng(FPDF_BITMAP bitmap, const std::string& filename);

  // Check `bitmap` matches `expectation_png_name`, where `expectation_png_name`
  // is the name of testing/resources/embedder_tests/expectation_png_name.png.
  static void CompareBitmap(FPDF_BITMAP bitmap,
                            std::string_view expectation_png_name);

  // Like CompareBitmap(), except instead of just adding ".png" to
  // `expectation_png_name`, this method will look for the expectation PNG using
  // several suffixes in order: "_$renderer_$os_$cpu.png", "_$renderer_$os.png",
  // "_$renderer.png", "_$os_$cpu.png", "_$os.png".
  //
  // $cpu is for macOS x86 only and is used to differentiate from macOS ARM.
  //
  // For example, with "hello_world", using Skia on macOS, the list of
  // expectation PNGs are:
  // - hello_world_skia_mac_x86.png
  // - hello_world_skia_mac.png
  // - hello_world_skia.png
  // - hello_world_mac_x86.png
  // - hello_world_mac.png
  // - hello_world.png
  //
  // This is similar to the behavior in testing/tools/pngdiffer.py.
  //
  // `options` can optionally be set to tolerate minor pixel discrepancies.
  // The default is exact matching.
  static void CompareBitmapWithExpectationSuffix(
      FPDF_BITMAP bitmap,
      std::string_view expectation_png_name,
      const DiffOptions& options = kExactDiffOptions);

  void ClearString() { data_string_.clear(); }
  const std::string& GetString() const { return data_string_; }

  static int GetBlockFromString(void* param,
                                unsigned long pos,
                                unsigned char* buf,
                                unsigned long size);

  // See comments in the respective non-Saved versions of these methods.
  ScopedSavedDoc OpenScopedSavedDocument();
  ScopedSavedDoc OpenScopedSavedDocumentWithPassword(
      const ByteString& password);
  ScopedSavedPage LoadScopedSavedPage(int page_index);

  // See comments for CompareBitmap() and CompareBitmapWithExpectationSuffix()
  // above.
  void VerifySavedRendering(FPDF_PAGE page,
                            std::string_view expectation_png_name);
  void VerifySavedRenderingWithExpectationSuffix(
      FPDF_PAGE page,
      std::string_view expectation_png_name,
      const DiffOptions& options = kExactDiffOptions);
  void VerifySavedDocument(std::string_view expectation_png_name);
  void VerifySavedDocumentWithExpectationSuffix(
      std::string_view expectation_png_name,
      const DiffOptions& options = kExactDiffOptions);

  void SetWholeFileAvailable();

#ifndef NDEBUG
  // For debugging purposes.
  // While open, write any data that gets passed to WriteBlockCallback() to
  // `filename`. This is typically used to capture data from FPDF_SaveAsCopy()
  // calls.
  void OpenPDFFileForWrite(const std::string& filename);
  void ClosePDFFileForWrite();
#endif

 private:
  static int WriteBlockCallback(FPDF_FILEWRITE* pFileWrite,
                                const void* data,
                                unsigned long size);

  // Helper method for the methods below.
  static int GetPageNumberForPage(const PageNumberToHandleMap& page_map,
                                  FPDF_PAGE page);
  // Find `page` inside `page_map_` and return the associated page number, or -1
  // if `page` cannot be found.
  int GetPageNumberForLoadedPage(FPDF_PAGE page) const;

  // Same as GetPageNumberForLoadedPage(), but with `saved_page_map_`.
  int GetPageNumberForSavedPage(FPDF_PAGE page) const;

  // Helpers for opening saved documents. These are intended for internal use
  // only. Callers should use the Scoped methods that manage lifetime
  // automatically.
  FPDF_DOCUMENT OpenSavedDocument();
  FPDF_DOCUMENT OpenSavedDocumentWithPassword(const ByteString& password);

  // Closes a document opened via OpenSavedDocument(). This must only be invoked
  // in documents opened by the helpers above. This is intended for internal use
  // in the destructor of the scoped methods.
  void CloseSavedDocument();

  // Helper for loading saved pages. Callers should use the Scoped methods that
  // manage lifetime automatically.
  FPDF_PAGE LoadSavedPage(int page_index);

  // Closes a page loaded via LoadSavedPage(). This must only be invoked in
  // pages loaded by the helper above.
  void CloseSavedPage(FPDF_PAGE page);

  void UnloadPageCommon(FPDF_PAGE page, bool do_events);
  FPDF_PAGE LoadPageCommon(int page_index, bool do_events);

  ScopedFPDFBitmap VerifySavedRenderingCommon(FPDF_PAGE page);
  ScopedFPDFBitmap VerifySavedDocumentCommon();

  // Keep `delegate_` after both possible pointees so it is destroyed first.
  std::unique_ptr<Delegate> default_delegate_;
  std::unique_ptr<Delegate> owned_delegate_;
  UnownedPtr<Delegate> delegate_;

#ifdef PDF_ENABLE_XFA
  int form_fill_info_version_ = 2;
#else   // PDF_ENABLE_XFA
  int form_fill_info_version_ = 1;
#endif  // PDF_ENABLE_XFA

  // must outlive `loader_`.
  std::vector<uint8_t> file_contents_;
  std::unique_ptr<TestLoader> loader_;
  FPDF_FILEACCESS file_access_;                       // must outlive `avail_`.
  std::unique_ptr<FakeFileAccess> fake_file_access_;  // must outlive `avail_`.
  ScopedFPDFAvail avail_;
  ScopedFPDFDocument document_;
  ScopedFPDFFormHandle form_handle_;
  PageNumberToHandleMap page_map_;

  FPDF_FILEACCESS saved_file_access_;  // must outlive `saved_avail_`.
  // must outlive `saved_avail_`.
  std::unique_ptr<FakeFileAccess> saved_fake_file_access_;
  ScopedFPDFAvail saved_avail_;
  ScopedFPDFDocument saved_document_;
  ScopedFPDFFormHandle saved_form_handle_;
  PageNumberToHandleMap saved_page_map_;

  std::string data_string_;
  std::string saved_document_file_data_;
  std::ofstream filestream_;
};

#endif  // TESTING_EMBEDDER_TEST_H_
