// Copyright 2014 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.

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

#ifndef FPDFSDK_FPDFXFA_CPDFXFA_CONTEXT_H_
#define FPDFSDK_FPDFXFA_CPDFXFA_CONTEXT_H_

#include <stdint.h>

#include <memory>
#include <vector>

#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fxcrt/cfx_timer.h"
#include "core/fxcrt/observed_ptr.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
#include "fxjs/gc/heap.h"
#include "v8/include/cppgc/persistent.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdoc.h"

class CFX_XMLDocument;
class CJS_Runtime;
class CPDFXFA_DocEnvironment;

enum LoadStatus {
  FXFA_LOADSTATUS_PRELOAD = 0,
  FXFA_LOADSTATUS_LOADING,
  FXFA_LOADSTATUS_LOADED,
  FXFA_LOADSTATUS_CLOSING,
};

// Per-process initializations.
void CPDFXFA_ModuleInit();
void CPDFXFA_ModuleDestroy();

class CPDFXFA_Context final : public CPDF_Document::Extension,
                              public CXFA_FFApp::CallbackIface {
 public:
  explicit CPDFXFA_Context(CPDF_Document* pPDFDoc);
  ~CPDFXFA_Context() override;

  bool LoadXFADoc();
  LoadStatus GetLoadStatus() const { return m_nLoadStatus; }
  FormType GetFormType() const { return m_FormType; }
  int GetOriginalPageCount() const { return m_nPageCount; }
  void SetOriginalPageCount(int count) {
    m_nPageCount = count;
    m_XFAPageList.resize(count);
  }

  CFX_XMLDocument* GetXMLDoc() { return m_pXML.get(); }
  CXFA_FFDoc* GetXFADoc() { return m_pXFADoc; }
  CXFA_FFDocView* GetXFADocView() const { return m_pXFADocView.Get(); }
  CPDFSDK_FormFillEnvironment* GetFormFillEnv() const {
    return m_pFormFillEnv.Get();
  }
  void SetFormFillEnv(CPDFSDK_FormFillEnvironment* pFormFillEnv);
  RetainPtr<CPDFXFA_Page> GetOrCreateXFAPage(int page_index);
  RetainPtr<CPDFXFA_Page> GetXFAPage(int page_index);
  RetainPtr<CPDFXFA_Page> GetXFAPage(CXFA_FFPageView* pPage) const;
  void ClearChangeMark();

  // CPDF_Document::Extension:
  CPDF_Document* GetPDFDoc() const override;
  int GetPageCount() const override;
  void DeletePage(int page_index) override;
  uint32_t GetUserPermissions() const override;
  bool ContainsExtensionForm() const override;
  bool ContainsExtensionFullForm() const override;
  bool ContainsExtensionForegroundForm() const override;

  // CXFA_FFApp::CallbackIface:
  WideString GetLanguage() override;
  WideString GetPlatform() override;
  WideString GetAppName() override;
  WideString GetAppTitle() const override;
  void Beep(uint32_t dwType) override;
  int32_t MsgBox(const WideString& wsMessage,
                 const WideString& wsTitle,
                 uint32_t dwIconType,
                 uint32_t dwButtonType) override;
  WideString Response(const WideString& wsQuestion,
                      const WideString& wsTitle,
                      const WideString& wsDefaultAnswer,
                      bool bMark) override;
  RetainPtr<IFX_SeekableReadStream> DownloadURL(
      const WideString& wsURL) override;
  bool PostRequestURL(const WideString& wsURL,
                      const WideString& wsData,
                      const WideString& wsContentType,
                      const WideString& wsEncode,
                      const WideString& wsHeader,
                      WideString& wsResponse) override;
  bool PutRequestURL(const WideString& wsURL,
                     const WideString& wsData,
                     const WideString& wsEncode) override;
  CFX_Timer::HandlerIface* GetTimerHandler() const override;
  cppgc::Heap* GetGCHeap() const override;

  bool SaveDatasetsPackage(const RetainPtr<IFX_SeekableStream>& pStream);
  bool SaveFormPackage(const RetainPtr<IFX_SeekableStream>& pStream);
  void SendPostSaveToXFADoc();
  void SendPreSaveToXFADoc(
      std::vector<RetainPtr<IFX_SeekableStream>>* fileList);

 private:
  CJS_Runtime* GetCJSRuntime() const;
  bool SavePackage(const RetainPtr<IFX_SeekableStream>& pStream,
                   XFA_HashCode code);

  FormType m_FormType = FormType::kNone;
  LoadStatus m_nLoadStatus = FXFA_LOADSTATUS_PRELOAD;
  int m_nPageCount = 0;

  // The order in which the following members are destroyed is critical.
  UnownedPtr<CPDF_Document> const m_pPDFDoc;
  std::unique_ptr<CFX_XMLDocument> m_pXML;
  ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
  std::vector<RetainPtr<CPDFXFA_Page>> m_XFAPageList;

  // Can't outlive |m_pFormFillEnv|.
  std::unique_ptr<CPDFXFA_DocEnvironment> m_pDocEnv;

  FXGCScopedHeap m_pGCHeap;
  cppgc::Persistent<CXFA_FFApp> m_pXFAApp;          // can't outlive |m_pGCHeap|
  cppgc::Persistent<CXFA_FFDoc> m_pXFADoc;          // Can't outlive |m_pGCHeap|
  cppgc::Persistent<CXFA_FFDocView> m_pXFADocView;  // Can't outlive |m_pGCHeap|
};

#endif  // FPDFSDK_FPDFXFA_CPDFXFA_CONTEXT_H_
