// 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

#include "public/fpdf_save.h"

#include <vector>

#include "core/fpdfapi/fpdf_edit/cpdf_creator.h"
#include "core/fpdfapi/fpdf_parser/cpdf_array.h"
#include "core/fpdfapi/fpdf_parser/cpdf_document.h"
#include "core/fpdfapi/fpdf_parser/cpdf_reference.h"
#include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h"
#include "core/fpdfapi/fpdf_parser/cpdf_string.h"
#include "core/fxcrt/fx_ext.h"
#include "fpdfsdk/fsdk_define.h"
#include "public/fpdf_edit.h"

#ifdef PDF_ENABLE_XFA
#include "fpdfsdk/fpdfxfa/fpdfxfa_app.h"
#include "fpdfsdk/fpdfxfa/fpdfxfa_doc.h"
#include "fpdfsdk/fpdfxfa/fpdfxfa_util.h"
#include "public/fpdf_formfill.h"
#include "xfa/fxfa/cxfa_eventparam.h"
#include "xfa/fxfa/xfa_checksum.h"
#include "xfa/fxfa/xfa_ffapp.h"
#include "xfa/fxfa/xfa_ffdocview.h"
#include "xfa/fxfa/xfa_ffwidgethandler.h"
#endif

#if _FX_OS_ == _FX_ANDROID_
#include "time.h"
#else
#include <ctime>
#endif

class CFX_IFileWrite final : public IFX_StreamWrite {
 public:
  CFX_IFileWrite();
  FX_BOOL Init(FPDF_FILEWRITE* pFileWriteStruct);
  FX_BOOL WriteBlock(const void* pData, size_t size) override;
  void Release() override;

 protected:
  ~CFX_IFileWrite() override {}

  FPDF_FILEWRITE* m_pFileWriteStruct;
};

CFX_IFileWrite::CFX_IFileWrite() {
  m_pFileWriteStruct = nullptr;
}

FX_BOOL CFX_IFileWrite::Init(FPDF_FILEWRITE* pFileWriteStruct) {
  if (!pFileWriteStruct)
    return FALSE;

  m_pFileWriteStruct = pFileWriteStruct;
  return TRUE;
}

FX_BOOL CFX_IFileWrite::WriteBlock(const void* pData, size_t size) {
  if (!m_pFileWriteStruct)
    return FALSE;

  m_pFileWriteStruct->WriteBlock(m_pFileWriteStruct, pData, size);
  return TRUE;
}

void CFX_IFileWrite::Release() {
  delete this;
}

namespace {

#ifdef PDF_ENABLE_XFA
bool SaveXFADocumentData(CPDFXFA_Document* pDocument,
                         std::vector<ScopedFileStream>* fileList) {
  if (!pDocument)
    return false;

  if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
      pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
    return true;

  if (!CPDFXFA_App::GetInstance()->GetXFAApp())
    return true;

  CXFA_FFDocView* pXFADocView = pDocument->GetXFADocView();
  if (!pXFADocView)
    return true;

  CPDF_Document* pPDFDocument = pDocument->GetPDFDoc();
  if (!pDocument)
    return false;

  CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
  if (!pRoot)
    return false;

  CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
  if (!pAcroForm)
    return false;

  CPDF_Object* pXFA = pAcroForm->GetObjectFor("XFA");
  if (!pXFA)
    return true;

  CPDF_Array* pArray = pXFA->AsArray();
  if (!pArray)
    return false;

  int size = pArray->GetCount();
  int iFormIndex = -1;
  int iDataSetsIndex = -1;
  int iTemplate = -1;
  int iLast = size - 2;
  for (int i = 0; i < size - 1; i++) {
    CPDF_Object* pPDFObj = pArray->GetObjectAt(i);
    if (!pPDFObj->IsString())
      continue;
    if (pPDFObj->GetString() == "form")
      iFormIndex = i + 1;
    else if (pPDFObj->GetString() == "datasets")
      iDataSetsIndex = i + 1;
    else if (pPDFObj->GetString() == "template")
      iTemplate = i + 1;
  }
  std::unique_ptr<CXFA_ChecksumContext> pContext(new CXFA_ChecksumContext);
  pContext->StartChecksum();

  // template
  if (iTemplate > -1) {
    CPDF_Stream* pTemplateStream = pArray->GetStreamAt(iTemplate);
    CPDF_StreamAcc streamAcc;
    streamAcc.LoadAllData(pTemplateStream);
    uint8_t* pData = (uint8_t*)streamAcc.GetData();
    uint32_t dwSize2 = streamAcc.GetSize();
    ScopedFileStream pTemplate(FX_CreateMemoryStream(pData, dwSize2));
    pContext->UpdateChecksum(pTemplate.get());
  }
  CPDF_Stream* pFormStream = nullptr;
  CPDF_Stream* pDataSetsStream = nullptr;
  if (iFormIndex != -1) {
    // Get form CPDF_Stream
    CPDF_Object* pFormPDFObj = pArray->GetObjectAt(iFormIndex);
    if (pFormPDFObj->IsReference()) {
      CPDF_Object* pFormDirectObj = pFormPDFObj->GetDirect();
      if (pFormDirectObj && pFormDirectObj->IsStream()) {
        pFormStream = (CPDF_Stream*)pFormDirectObj;
      }
    } else if (pFormPDFObj->IsStream()) {
      pFormStream = (CPDF_Stream*)pFormPDFObj;
    }
  }

  if (iDataSetsIndex != -1) {
    // Get datasets CPDF_Stream
    CPDF_Object* pDataSetsPDFObj = pArray->GetObjectAt(iDataSetsIndex);
    if (pDataSetsPDFObj->IsReference()) {
      CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
      CPDF_Object* pDataSetsDirectObj = pDataSetsRefObj->GetDirect();
      if (pDataSetsDirectObj && pDataSetsDirectObj->IsStream()) {
        pDataSetsStream = (CPDF_Stream*)pDataSetsDirectObj;
      }
    } else if (pDataSetsPDFObj->IsStream()) {
      pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
    }
  }
  // L"datasets"
  {
    ScopedFileStream pDsfileWrite(FX_CreateMemoryStream());
    if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Datasets,
                                           pDsfileWrite.get(), nullptr) &&
        pDsfileWrite->GetSize() > 0) {
      // Datasets
      pContext->UpdateChecksum(pDsfileWrite.get());
      pContext->FinishChecksum();
      CPDF_Dictionary* pDataDict =
          new CPDF_Dictionary(pPDFDocument->GetByteStringPool());
      if (iDataSetsIndex != -1) {
        if (pDataSetsStream)
          pDataSetsStream->InitStreamFromFile(pDsfileWrite.get(), pDataDict);
      } else {
        CPDF_Stream* pData = new CPDF_Stream;
        pData->InitStreamFromFile(pDsfileWrite.get(), pDataDict);
        iLast = pArray->GetCount() - 2;
        pArray->InsertAt(iLast, new CPDF_String("datasets", FALSE));
        pArray->InsertAt(
            iLast + 1,
            new CPDF_Reference(pPDFDocument,
                               pPDFDocument->AddIndirectObject(pData)));
      }
      fileList->push_back(std::move(pDsfileWrite));
    }
  }
  // L"form"
  {
    ScopedFileStream pfileWrite(FX_CreateMemoryStream());
    if (pXFADocView->GetDoc()->SavePackage(XFA_HASHCODE_Form, pfileWrite.get(),
                                           pContext.get()) &&
        pfileWrite->GetSize() > 0) {
      CPDF_Dictionary* pDataDict =
          new CPDF_Dictionary(pPDFDocument->GetByteStringPool());
      if (iFormIndex != -1) {
        if (pFormStream)
          pFormStream->InitStreamFromFile(pfileWrite.get(), pDataDict);
      } else {
        CPDF_Stream* pData = new CPDF_Stream;
        pData->InitStreamFromFile(pfileWrite.get(), pDataDict);
        iLast = pArray->GetCount() - 2;
        pArray->InsertAt(iLast, new CPDF_String("form", FALSE));
        pArray->InsertAt(
            iLast + 1,
            new CPDF_Reference(pPDFDocument,
                               pPDFDocument->AddIndirectObject(pData)));
      }
      fileList->push_back(std::move(pfileWrite));
    }
  }
  return true;
}

bool SendPostSaveToXFADoc(CPDFXFA_Document* pDocument) {
  if (!pDocument)
    return false;

  if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
      pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
    return true;

  CXFA_FFDocView* pXFADocView = pDocument->GetXFADocView();
  if (!pXFADocView)
    return false;

  CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
  std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
      pXFADocView->CreateWidgetAccIterator());
  while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
    CXFA_EventParam preParam;
    preParam.m_eType = XFA_EVENT_PostSave;
    pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
  }
  pXFADocView->UpdateDocView();
  pDocument->ClearChangeMark();
  return true;
}

bool SendPreSaveToXFADoc(CPDFXFA_Document* pDocument,
                         std::vector<ScopedFileStream>* fileList) {
  if (pDocument->GetDocType() != DOCTYPE_DYNAMIC_XFA &&
      pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
    return true;

  CXFA_FFDocView* pXFADocView = pDocument->GetXFADocView();
  if (!pXFADocView)
    return true;

  CXFA_FFWidgetHandler* pWidgetHander = pXFADocView->GetWidgetHandler();
  std::unique_ptr<CXFA_WidgetAccIterator> pWidgetAccIterator(
      pXFADocView->CreateWidgetAccIterator());
  while (CXFA_WidgetAcc* pWidgetAcc = pWidgetAccIterator->MoveToNext()) {
    CXFA_EventParam preParam;
    preParam.m_eType = XFA_EVENT_PreSave;
    pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
  }
  pXFADocView->UpdateDocView();
  return SaveXFADocumentData(pDocument, fileList);
}
#endif  // PDF_ENABLE_XFA

bool FPDF_Doc_Save(FPDF_DOCUMENT document,
                   FPDF_FILEWRITE* pFileWrite,
                   FPDF_DWORD flags,
                   FPDF_BOOL bSetVersion,
                   int fileVerion) {
  CPDF_Document* pPDFDoc = CPDFDocumentFromFPDFDocument(document);
  if (!pPDFDoc)
    return 0;

#ifdef PDF_ENABLE_XFA
  CPDFXFA_Document* pDoc = static_cast<CPDFXFA_Document*>(document);
  std::vector<ScopedFileStream> fileList;
  SendPreSaveToXFADoc(pDoc, &fileList);
#endif  // PDF_ENABLE_XFA

  if (flags < FPDF_INCREMENTAL || flags > FPDF_REMOVE_SECURITY)
    flags = 0;

  CPDF_Creator FileMaker(pPDFDoc);
  if (bSetVersion)
    FileMaker.SetFileVersion(fileVerion);
  if (flags == FPDF_REMOVE_SECURITY) {
    flags = 0;
    FileMaker.RemoveSecurity();
  }

  CFX_IFileWrite* pStreamWrite = new CFX_IFileWrite;
  pStreamWrite->Init(pFileWrite);
  bool bRet = FileMaker.Create(pStreamWrite, flags);
#ifdef PDF_ENABLE_XFA
  SendPostSaveToXFADoc(pDoc);
#endif  // PDF_ENABLE_XFA
  pStreamWrite->Release();
  return bRet;
}

}  // namespace

DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveAsCopy(FPDF_DOCUMENT document,
                                            FPDF_FILEWRITE* pFileWrite,
                                            FPDF_DWORD flags) {
  return FPDF_Doc_Save(document, pFileWrite, flags, FALSE, 0);
}

DLLEXPORT FPDF_BOOL STDCALL FPDF_SaveWithVersion(FPDF_DOCUMENT document,
                                                 FPDF_FILEWRITE* pFileWrite,
                                                 FPDF_DWORD flags,
                                                 int fileVersion) {
  return FPDF_Doc_Save(document, pFileWrite, flags, TRUE, fileVersion);
}
