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

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#ifndef FPDFSDK_CPDFSDK_FORMFILLENVIRONMENT_H_
#define FPDFSDK_CPDFSDK_FORMFILLENVIRONMENT_H_

#include <stdint.h>

#include <map>
#include <memory>
#include <set>
#include <utility>
#include <vector>

#include "core/fpdfapi/page/cpdf_occontext.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfdoc/cpdf_aaction.h"
#include "core/fxcrt/cfx_timer.h"
#include "core/fxcrt/mask.h"
#include "core/fxcrt/observed_ptr.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
#include "fpdfsdk/cpdfsdk_annot.h"
#include "fpdfsdk/formfiller/cffl_interactiveformfiller.h"
#include "fpdfsdk/pwl/cpwl_wnd.h"
#include "fpdfsdk/pwl/ipwl_fillernotify.h"
#include "public/fpdf_formfill.h"
#include "third_party/base/span.h"

class CPDF_Action;
class CPDF_FormField;
class CPDFSDK_InteractiveForm;
class CPDFSDK_PageView;
class IJS_EventContext;
class IJS_Runtime;
class IPDF_Page;
struct CFFL_FieldAction;

// NOTE: |bsUTF16LE| must outlive the use of the result. Care must be taken
// since modifying the result would impact |bsUTF16LE|.
FPDF_WIDESTRING AsFPDFWideString(ByteString* bsUTF16LE);

// The CPDFSDK_FormFillEnvironment is "owned" by the embedder across the
// C API as a FPDF_FormHandle, and may pop out of existence at any time,
// so long as the associated embedder-owned FPDF_Document outlives it.
// Pointers from objects in the FPDF_Document ownership hierarchy should
// be ObservedPtr<> so as to clear themselves when the embedder "exits"
// the form fill environment.  Pointers from objects in this ownership
// heirarcy to objects in the FPDF_Document ownership hierarcy should be
// UnownedPtr<>, as should pointers from objects in this ownership
// hierarcy back to the form fill environment itself, so as to flag any
// lingering lifetime issues via the memory tools.

class CPDFSDK_FormFillEnvironment final
    : public CFX_Timer::HandlerIface,
      public CFFL_InteractiveFormFiller::CallbackIface {
 public:
  CPDFSDK_FormFillEnvironment(CPDF_Document* pDoc, FPDF_FORMFILLINFO* pFFinfo);

  ~CPDFSDK_FormFillEnvironment() override;

  // TimerHandlerIface:
  int32_t SetTimer(int32_t uElapse, TimerCallback lpTimerFunc) override;
  void KillTimer(int32_t nTimerID) override;

  // CFFL_InteractiveFormFiller::CallbackIface:
  void InvalidateRect(CPDFSDK_Widget* widget,
                      const CFX_FloatRect& rect) override;
  void OutputSelectedRect(CFFL_FormField* pFormField,
                          const CFX_FloatRect& rect) override;
  bool IsSelectionImplemented() const override;
  void SetCursor(IPWL_FillerNotify::CursorStyle nCursorType) override;
  void OnSetFieldInputFocus(const WideString& text) override;
  void OnCalculate(ObservedPtr<CPDFSDK_Annot>& pAnnot) override;
  void OnFormat(ObservedPtr<CPDFSDK_Annot>& pAnnot) override;
  void Invalidate(IPDF_Page* page, const FX_RECT& rect) override;
  CPDFSDK_PageView* GetOrCreatePageView(IPDF_Page* pUnderlyingPage) override;
  CPDFSDK_PageView* GetPageView(IPDF_Page* pUnderlyingPage) override;
  CFX_Timer::HandlerIface* GetTimerHandler() override;
  CPDFSDK_Annot* GetFocusAnnot() const override;
  bool SetFocusAnnot(ObservedPtr<CPDFSDK_Annot>& pAnnot) override;
  bool HasPermissions(uint32_t flags) const override;
  void OnChange() override;

  CPDFSDK_PageView* GetPageViewAtIndex(int nIndex);
  void RemovePageView(IPDF_Page* pUnderlyingPage);
  void UpdateAllViews(CPDFSDK_Annot* pAnnot);

  bool KillFocusAnnot(Mask<FWL_EVENTFLAG> nFlags);
  void ClearAllFocusedAnnots();

  int GetPageCount() const;

  bool GetChangeMark() const { return m_bChangeMask; }
  void SetChangeMark() { m_bChangeMask = true; }
  void ClearChangeMark() { m_bChangeMask = false; }

  void ProcJavascriptAction();
  bool ProcOpenAction();

  void ExecuteNamedAction(const ByteString& namedAction);
  void DoURIAction(const ByteString& bsURI, Mask<FWL_EVENTFLAG> modifiers);
  void DoGoToAction(int nPageIndex,
                    int zoomMode,
                    pdfium::span<float> fPosArray);

  CPDF_Document* GetPDFDocument() const { return m_pCPDFDoc; }
  CPDF_Document::Extension* GetDocExtension() const {
    return m_pCPDFDoc->GetExtension();
  }

  bool IsJSPlatformPresent() const { return m_pInfo && m_pInfo->m_pJsPlatform; }
  IPDF_JSPLATFORM* GetJSPlatform() const {
    return m_pInfo ? m_pInfo->m_pJsPlatform : nullptr;
  }

  // Actions.
  bool DoActionDocOpen(const CPDF_Action& action);
  bool DoActionJavaScript(const CPDF_Action& JsAction, WideString csJSName);
  bool DoActionPage(const CPDF_Action& action, CPDF_AAction::AActionType eType);
  bool DoActionDocument(const CPDF_Action& action,
                        CPDF_AAction::AActionType eType);
  bool DoActionField(const CPDF_Action& action,
                     CPDF_AAction::AActionType type,
                     CPDF_FormField* pFormField,
                     CFFL_FieldAction* data);
  bool DoActionFieldJavaScript(const CPDF_Action& JsAction,
                               CPDF_AAction::AActionType type,
                               CPDF_FormField* pFormField,
                               CFFL_FieldAction* data);
  bool DoActionLink(const CPDF_Action& action,
                    CPDF_AAction::AActionType type,
                    Mask<FWL_EVENTFLAG> modifiers);
  bool DoActionDestination(const CPDF_Dest& dest);
  void DoActionNoJs(const CPDF_Action& action, CPDF_AAction::AActionType type);
  void DoActionGoTo(const CPDF_Action& action);
  void DoActionLaunch(const CPDF_Action& action);
  void DoActionURI(const CPDF_Action& action, Mask<FWL_EVENTFLAG> modifiers);
  void DoActionNamed(const CPDF_Action& action);
  bool DoActionHide(const CPDF_Action& action);
  bool DoActionSubmitForm(const CPDF_Action& action);
  void DoActionResetForm(const CPDF_Action& action);

#ifdef PDF_ENABLE_V8
  CPDFSDK_PageView* GetCurrentView();
  IPDF_Page* GetCurrentPage() const;

  WideString GetLanguage();
  WideString GetPlatform();

  int JS_appAlert(const WideString& Msg,
                  const WideString& Title,
                  int Type,
                  int Icon);
  int JS_appResponse(const WideString& Question,
                     const WideString& Title,
                     const WideString& Default,
                     const WideString& cLabel,
                     FPDF_BOOL bPassword,
                     pdfium::span<uint8_t> response);
  void JS_appBeep(int nType);
  WideString JS_fieldBrowse();
  void JS_docmailForm(pdfium::span<const uint8_t> mailData,
                      FPDF_BOOL bUI,
                      const WideString& To,
                      const WideString& Subject,
                      const WideString& CC,
                      const WideString& BCC,
                      const WideString& Msg);
  void JS_docprint(FPDF_BOOL bUI,
                   int nStart,
                   int nEnd,
                   FPDF_BOOL bSilent,
                   FPDF_BOOL bShrinkToFit,
                   FPDF_BOOL bPrintAsImage,
                   FPDF_BOOL bReverse,
                   FPDF_BOOL bAnnotations);
  void JS_docgotoPage(int nPageNum);
  WideString JS_docGetFilePath();

#ifdef PDF_ENABLE_XFA
  int GetPageViewCount() const;
  void DisplayCaret(IPDF_Page* page,
                    FPDF_BOOL bVisible,
                    double left,
                    double top,
                    double right,
                    double bottom);
  int GetCurrentPageIndex() const;
  void SetCurrentPage(int iCurPage);

  // TODO(dsinclair): This should probably change to PDFium?
  WideString FFI_GetAppName() const { return WideString(L"Acrobat"); }

  void GotoURL(const WideString& wsURL);
  FS_RECTF GetPageViewRect(IPDF_Page* page);
  bool PopupMenu(IPDF_Page* page, int menuFlag, const CFX_PointF& pt);
  void EmailTo(FPDF_FILEHANDLER* fileHandler,
               FPDF_WIDESTRING pTo,
               FPDF_WIDESTRING pSubject,
               FPDF_WIDESTRING pCC,
               FPDF_WIDESTRING pBcc,
               FPDF_WIDESTRING pMsg);
  void UploadTo(FPDF_FILEHANDLER* fileHandler,
                int fileFlag,
                FPDF_WIDESTRING uploadTo);
  FPDF_FILEHANDLER* OpenFile(int fileType,
                             FPDF_WIDESTRING wsURL,
                             const char* mode);
  RetainPtr<IFX_SeekableReadStream> DownloadFromURL(const WideString& url);
  WideString PostRequestURL(const WideString& wsURL,
                            const WideString& wsData,
                            const WideString& wsContentType,
                            const WideString& wsEncode,
                            const WideString& wsHeader);
  FPDF_BOOL PutRequestURL(const WideString& wsURL,
                          const WideString& wsData,
                          const WideString& wsEncode);

  void PageEvent(int iPageCount, uint32_t dwEventType) const;
#endif  // PDF_ENABLE_XFA
#endif  // PDF_ENABLE_V8

  WideString GetFilePath() const;
  ByteString GetAppName() const { return ByteString(); }
  FPDF_FORMFILLINFO* GetFormFillInfo() const { return m_pInfo; }
  void SubmitForm(pdfium::span<const uint8_t> form_data, const WideString& URL);

  void SetFocusableAnnotSubtypes(
      const std::vector<CPDF_Annot::Subtype>& focusableAnnotTypes) {
    m_FocusableAnnotTypes = focusableAnnotTypes;
  }
  const std::vector<CPDF_Annot::Subtype>& GetFocusableAnnotSubtypes() const {
    return m_FocusableAnnotTypes;
  }

  // Never returns null.
  CFFL_InteractiveFormFiller* GetInteractiveFormFiller() {
    return m_pInteractiveFormFiller.get();
  }

  IJS_Runtime* GetIJSRuntime();                   // Creates if not present.
  CPDFSDK_InteractiveForm* GetInteractiveForm();  // Creates if not present.

 private:
  using RunScriptCallback = std::function<void(IJS_EventContext* context)>;

  IPDF_Page* GetPage(int nIndex) const;
  void OnSetFieldInputFocusInternal(const WideString& text, bool bFocus);
  void SendOnFocusChange(ObservedPtr<CPDFSDK_Annot>& pAnnot);

  // Support methods for Actions.
  void RunScript(const WideString& script, const RunScriptCallback& cb);
  bool ExecuteDocumentOpenAction(const CPDF_Action& action,
                                 std::set<const CPDF_Dictionary*>* visited);
  bool ExecuteDocumentPageAction(const CPDF_Action& action,
                                 CPDF_AAction::AActionType type,
                                 std::set<const CPDF_Dictionary*>* visited);
  bool ExecuteFieldAction(const CPDF_Action& action,
                          CPDF_AAction::AActionType type,
                          CPDF_FormField* pFormField,
                          CFFL_FieldAction* data,
                          std::set<const CPDF_Dictionary*>* visited);
  void RunDocumentPageJavaScript(CPDF_AAction::AActionType type,
                                 const WideString& script);
  void RunDocumentOpenJavaScript(const WideString& sScriptName,
                                 const WideString& script);
  void RunFieldJavaScript(CPDF_FormField* pFormField,
                          CPDF_AAction::AActionType type,
                          CFFL_FieldAction* data,
                          const WideString& script);
  bool IsValidField(const CPDF_Dictionary* pFieldDict);

  UnownedPtr<FPDF_FORMFILLINFO> const m_pInfo;
  std::unique_ptr<IJS_Runtime> m_pIJSRuntime;

  // Iterator stability guarantees as provided by std::map<> required.
  std::map<IPDF_Page*, std::unique_ptr<CPDFSDK_PageView>> m_PageMap;

  std::unique_ptr<CPDFSDK_InteractiveForm> m_pInteractiveForm;
  ObservedPtr<CPDFSDK_Annot> m_pFocusAnnot;
  UnownedPtr<CPDF_Document> const m_pCPDFDoc;
  std::unique_ptr<CFFL_InteractiveFormFiller> m_pInteractiveFormFiller;
  bool m_bChangeMask = false;
  bool m_bBeingDestroyed = false;

  // Holds the list of focusable annot types.
  // Annotations of type WIDGET are by default focusable.
  std::vector<CPDF_Annot::Subtype> m_FocusableAnnotTypes = {
      CPDF_Annot::Subtype::WIDGET};
};

#endif  // FPDFSDK_CPDFSDK_FORMFILLENVIRONMENT_H_
