// 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_edit.h"
#include "../../public/fpdf_formfill.h"
#include "../../public/fpdf_save.h"
#include "../include/fsdk_define.h"
#include "../include/fpdfxfa/fpdfxfa_doc.h"
#include "../include/fpdfxfa/fpdfxfa_app.h"
#include "../include/fpdfxfa/fpdfxfa_util.h"

#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 );
	virtual	FX_BOOL		WriteBlock(const void* pData, size_t size) override;
	virtual void		Release() override {}

protected:
	FPDF_FILEWRITE*		m_pFileWriteStruct;
};

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

FX_BOOL CFX_IFileWrite::Init( FPDF_FILEWRITE * pFileWriteStruct )
{
	if (!pFileWriteStruct)
		return FALSE;
	else
	{
		m_pFileWriteStruct = pFileWriteStruct;
	}
	return TRUE;
}

FX_BOOL CFX_IFileWrite::WriteBlock(const void* pData, size_t size)
{
	if (m_pFileWriteStruct)
	{
		m_pFileWriteStruct->WriteBlock( m_pFileWriteStruct, pData, size );
		return TRUE;
	}
	else
		return FALSE;
}

#define  XFA_DATASETS 0
#define  XFA_FORMS    1

FX_BOOL _SaveXFADocumentData(CPDFXFA_Document* pDocument, CFX_PtrArray& fileList)
{
	if (!pDocument)
		return FALSE;
	if (pDocument->GetDocType() != DOCTYPE_DYNIMIC_XFA && pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
		return TRUE;
	if (!CPDFXFA_App::GetInstance()->GetXFAApp())
		return TRUE;

	IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
	if (NULL == pXFADocView)
		return TRUE;

	IXFA_DocHandler *pXFADocHandler = CPDFXFA_App::GetInstance()->GetXFAApp()->GetDocHandler();
	CPDF_Document * pPDFDocument = pDocument->GetPDFDoc();
	if (pDocument == NULL)
		return FALSE;

	CPDF_Dictionary* pRoot = pPDFDocument->GetRoot();
	if (pRoot == NULL)
		return FALSE;
	CPDF_Dictionary* pAcroForm = pRoot->GetDict("AcroForm");
	if (NULL == pAcroForm)
		return FALSE;
	CPDF_Object* pXFA = pAcroForm->GetElement("XFA");
	if (pXFA == NULL)
		return TRUE;
	if(pXFA->GetType() != PDFOBJ_ARRAY)
		return FALSE;
	CPDF_Array* pArray = pXFA->GetArray();
	if (NULL == 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->GetElement(i);
		if (pPDFObj->GetType() != PDFOBJ_STRING)
			continue;
		if (pPDFObj->GetString() == "form")
			iFormIndex = i+1;
		else if (pPDFObj->GetString() == "datasets")
			iDataSetsIndex = i+1;
		else if (pPDFObj->GetString() == FX_BSTRC("template"))
			iTemplate = i + 1;
	}
	IXFA_ChecksumContext* pContext = NULL;
#define XFA_USECKSUM
#ifdef XFA_USECKSUM
	//Checksum
	pContext = XFA_Checksum_Create();
	FXSYS_assert(pContext);
	pContext->StartChecksum();

	//template
	if (iTemplate > -1)
	{
		CPDF_Stream *pTemplateStream = pArray->GetStream(iTemplate);
		CPDF_StreamAcc streamAcc;
		streamAcc.LoadAllData(pTemplateStream);
		uint8_t* pData = (uint8_t*)streamAcc.GetData();
		FX_DWORD dwSize2 = streamAcc.GetSize();
		IFX_FileStream *pTemplate = FX_CreateMemoryStream(pData, dwSize2);
		pContext->UpdateChecksum((IFX_FileRead*)pTemplate);
		pTemplate->Release();
	}
#endif
	CPDF_Stream* pFormStream = NULL;
	CPDF_Stream* pDataSetsStream = NULL;
	if (iFormIndex != -1)
	{
		//Get form CPDF_Stream
		CPDF_Object* pFormPDFObj = pArray->GetElement(iFormIndex);
		if (pFormPDFObj->GetType() == PDFOBJ_REFERENCE)
		{
			CPDF_Reference* pFormRefObj = (CPDF_Reference*)pFormPDFObj;
			CPDF_Object* pFormDircetObj = pFormPDFObj->GetDirect();
			if (NULL != pFormDircetObj && pFormDircetObj->GetType() == PDFOBJ_STREAM)
			{
				pFormStream = (CPDF_Stream*)pFormDircetObj;
			}
		}
		else if (pFormPDFObj->GetType() == PDFOBJ_STREAM)
		{
			pFormStream = (CPDF_Stream*)pFormPDFObj;
		}
	}

	if (iDataSetsIndex != -1)
	{
		//Get datasets CPDF_Stream
		CPDF_Object* pDataSetsPDFObj = pArray->GetElement(iDataSetsIndex);
		if (pDataSetsPDFObj->GetType() == PDFOBJ_REFERENCE)
		{
			CPDF_Reference* pDataSetsRefObj = (CPDF_Reference*)pDataSetsPDFObj;
			CPDF_Object* pDataSetsDircetObj = pDataSetsRefObj->GetDirect();
			if (NULL != pDataSetsDircetObj && pDataSetsDircetObj->GetType() == PDFOBJ_STREAM)
			{
				pDataSetsStream = (CPDF_Stream*)pDataSetsDircetObj;
			}
		}
		else if (pDataSetsPDFObj->GetType() == PDFOBJ_STREAM)
		{
			pDataSetsStream = (CPDF_Stream*)pDataSetsPDFObj;
		}
	}
	//end
	//L"datasets"
	{
		IFX_FileStream* pDsfileWrite = FX_CreateMemoryStream();
		if ( NULL == pDsfileWrite )
		{
			pContext->Release();
			pDsfileWrite->Release();
			return FALSE;
		}
		if (pXFADocHandler->SavePackage(pXFADocView->GetDoc(), CFX_WideStringC(L"datasets"), pDsfileWrite) && pDsfileWrite->GetSize()>0)
		{
#ifdef XFA_USECKSUM
		//Datasets
		pContext->UpdateChecksum((IFX_FileRead*)pDsfileWrite);
		pContext->FinishChecksum();
#endif
			CPDF_Dictionary* pDataDict = FX_NEW CPDF_Dictionary;
			if (iDataSetsIndex != -1)
			{
				if (pDataSetsStream)
					pDataSetsStream->InitStream(pDsfileWrite, pDataDict);
			}
			else
			{
				CPDF_Stream* pData = FX_NEW CPDF_Stream(NULL, 0, NULL);
				pData->InitStream(pDsfileWrite, pDataDict);
				FX_DWORD AppStreamobjnum = pPDFDocument->AddIndirectObject(pData);
				CPDF_Reference* pRef = (CPDF_Reference*)pPDFDocument->GetIndirectObject(AppStreamobjnum);
				{
					iLast = pArray->GetCount() -2;
					pArray->InsertAt(iLast,CPDF_String::Create("datasets"));
					pArray->InsertAt(iLast+1, pData, pPDFDocument);
				}
			}
			fileList.Add(pDsfileWrite);
		}
	}


	//L"form"
	{

		IFX_FileStream* pfileWrite = FX_CreateMemoryStream();
		if (NULL == pfileWrite)
		{
			pContext->Release();
			return FALSE;
		}
		if(pXFADocHandler->SavePackage(pXFADocView->GetDoc(), CFX_WideStringC(L"form"), pfileWrite, pContext) && pfileWrite > 0)
		{
			CPDF_Dictionary* pDataDict = FX_NEW CPDF_Dictionary;
			if (iFormIndex != -1)
			{
				if (pFormStream)
					pFormStream->InitStream(pfileWrite, pDataDict);
			}
			else
			{
				CPDF_Stream* pData = FX_NEW CPDF_Stream(NULL, 0, NULL);
				pData->InitStream(pfileWrite, pDataDict);
				FX_DWORD AppStreamobjnum = pPDFDocument->AddIndirectObject(pData);
				CPDF_Reference* pRef = (CPDF_Reference*)pPDFDocument->GetIndirectObject(AppStreamobjnum);
				{
					iLast = pArray->GetCount() -2;
					pArray->InsertAt(iLast, CPDF_String::Create("form"));
					pArray->InsertAt(iLast+1, pData, pPDFDocument);
				}
			}
			fileList.Add(pfileWrite);
		}
	}
	pContext->Release();
	return TRUE;
}


FX_BOOL _SendPostSaveToXFADoc(CPDFXFA_Document* pDocument)
{
	if (!pDocument)
		return FALSE;

	if (pDocument->GetDocType() != DOCTYPE_DYNIMIC_XFA && pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
		return TRUE;

	IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
	if (NULL == pXFADocView)
		return FALSE;
	IXFA_WidgetHandler* pWidgetHander =  pXFADocView->GetWidgetHandler();

	CXFA_WidgetAcc* pWidgetAcc = NULL;
	IXFA_WidgetAccIterator* pWidgetAccIterator = pXFADocView->CreateWidgetAccIterator();
	pWidgetAcc = pWidgetAccIterator->MoveToNext();
	while(pWidgetAcc)
	{
		CXFA_EventParam preParam;
		preParam.m_eType =  XFA_EVENT_PostSave;
		pWidgetHander->ProcessEvent(pWidgetAcc,&preParam);
		pWidgetAcc = pWidgetAccIterator->MoveToNext();
	}
	pWidgetAccIterator->Release();
	pXFADocView->UpdateDocView();
	pDocument->_ClearChangeMark();
	return TRUE;
}


FX_BOOL _SendPreSaveToXFADoc(CPDFXFA_Document* pDocument, CFX_PtrArray& fileList)
{
	if (pDocument->GetDocType() != DOCTYPE_DYNIMIC_XFA && pDocument->GetDocType() != DOCTYPE_STATIC_XFA)
		return TRUE;
	IXFA_DocView* pXFADocView = pDocument->GetXFADocView();
	if (NULL == pXFADocView)
		return TRUE;
	IXFA_WidgetHandler* pWidgetHander =  pXFADocView->GetWidgetHandler();
	CXFA_WidgetAcc* pWidgetAcc = NULL;
	IXFA_WidgetAccIterator* pWidgetAccIterator = pXFADocView->CreateWidgetAccIterator();
	pWidgetAcc = pWidgetAccIterator->MoveToNext();
	while(pWidgetAcc)
	{
		CXFA_EventParam preParam;
		preParam.m_eType =  XFA_EVENT_PreSave;
		pWidgetHander->ProcessEvent(pWidgetAcc, &preParam);
		pWidgetAcc = pWidgetAccIterator->MoveToNext();
	}
	pWidgetAccIterator->Release();
	pXFADocView->UpdateDocView();
	return _SaveXFADocumentData(pDocument, fileList);
}

FPDF_BOOL _FPDF_Doc_Save(FPDF_DOCUMENT document, FPDF_FILEWRITE * pFileWrite,FPDF_DWORD flags, FPDF_BOOL bSetVersion,
						 int fileVerion)
{
	CPDFXFA_Document* pDoc = (CPDFXFA_Document*)document;

	CFX_PtrArray fileList;

	_SendPreSaveToXFADoc(pDoc, fileList);

	CPDF_Document* pPDFDoc = pDoc->GetPDFDoc();
	if (!pPDFDoc)
		return 0;

	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 = NULL;
	FX_BOOL bRet;
	pStreamWrite = new CFX_IFileWrite;
	pStreamWrite->Init( pFileWrite );
	bRet = FileMaker.Create(pStreamWrite, flags);

	_SendPostSaveToXFADoc(pDoc);
	//pDoc->_ClearChangeMark();

	for (int i = 0; i < fileList.GetSize(); i++)
	{
		IFX_FileStream* pFile = (IFX_FileStream*)fileList.GetAt(i);
		pFile->Release();
	}
	fileList.RemoveAll();

	delete pStreamWrite;
	return bRet;
}

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);
}

