// 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 <memory>
#include <vector>

#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fxcrt/fx_system.h"
#include "core/fxcrt/observed_ptr.h"
#include "core/fxcrt/timerhandler_iface.h"
#include "core/fxcrt/unowned_ptr.h"
#include "fpdfsdk/cpdfsdk_formfillenvironment.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
#include "fxjs/gc/heap.h"
#include "xfa/fxfa/cxfa_ffdoc.h"

class CJS_Runtime;
class CPDFXFA_DocEnvironment;

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

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

  bool LoadXFADoc();
  CXFA_FFDoc* GetXFADoc() { return m_pXFADoc.get(); }
  CXFA_FFDocView* GetXFADocView() const { return m_pXFADocView.Get(); }
  cppgc::Heap* GetGCHeap() { return m_pGCHeap.get(); }
  FormType GetFormType() const { return m_FormType; }
  CPDFSDK_FormFillEnvironment* GetFormFillEnv() const {
    return m_pFormFillEnv.Get();
  }
  void SetFormFillEnv(CPDFSDK_FormFillEnvironment* pFormFillEnv);
  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;

  // IFXA_AppProvider:
  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;
  TimerHandlerIface* GetTimerHandler() 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:
  friend class CPDFXFA_DocEnvironment;

  int GetOriginalPageCount() const { return m_nPageCount; }
  void SetOriginalPageCount(int count) {
    m_nPageCount = count;
    m_XFAPageList.resize(count);
  }

  LoadStatus GetLoadStatus() const { return m_nLoadStatus; }
  std::vector<RetainPtr<CPDFXFA_Page>>* GetXFAPageList() {
    return &m_XFAPageList;
  }

  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;
  FXGCScopedHeap m_pGCHeap;
  ObservedPtr<CPDFSDK_FormFillEnvironment> m_pFormFillEnv;
  std::unique_ptr<CXFA_FFApp> const m_pXFAApp;
  std::vector<RetainPtr<CPDFXFA_Page>> m_XFAPageList;

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

  std::unique_ptr<CXFA_FFDoc> m_pXFADoc;
  UnownedPtr<CXFA_FFDocView> m_pXFADocView;
};

#endif  // FPDFSDK_FPDFXFA_CPDFXFA_CONTEXT_H_
