// 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) {}

    // Equivalent to FPDF_FORMFILLINFO::FFI_ExecuteNamedAction().
    virtual void ExecuteNamedAction(FPDF_BYTESTRING name) {}
  };

  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_
