// 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 "../../../core/include/fdrm/fx_crypt.h"
#include "../../include/javascript/JavaScript.h"
#include "../../include/javascript/IJavaScript.h"
#include "../../include/javascript/JS_GlobalData.h"

#define JS_MAXGLOBALDATA			(1024 * 4 - 8)

/* --------------------- CJS_GlobalVariableArray --------------------- */

CJS_GlobalVariableArray::CJS_GlobalVariableArray()
{
}

CJS_GlobalVariableArray::~CJS_GlobalVariableArray()
{
	Empty();
}

void CJS_GlobalVariableArray::Copy(const CJS_GlobalVariableArray& array)
{
	Empty();
	for (int i=0,sz=array.Count(); i<sz; i++)
	{
		CJS_KeyValue* pOldObjData = array.GetAt(i);
		ASSERT(pOldObjData != NULL);

		switch (pOldObjData->nType)
		{
		case JS_GLOBALDATA_TYPE_NUMBER:
			{
				CJS_KeyValue* pNewObjData = new CJS_KeyValue;
				pNewObjData->sKey = pOldObjData->sKey;
				pNewObjData->nType = pOldObjData->nType;
				pNewObjData->dData = pOldObjData->dData;
				Add(pNewObjData);
			}
			break;
		case JS_GLOBALDATA_TYPE_BOOLEAN:
			{
				CJS_KeyValue* pNewObjData = new CJS_KeyValue;
				pNewObjData->sKey = pOldObjData->sKey;
				pNewObjData->nType = pOldObjData->nType;
				pNewObjData->bData = pOldObjData->bData;
				Add(pNewObjData);
			}
			break;
		case JS_GLOBALDATA_TYPE_STRING:
			{
				CJS_KeyValue* pNewObjData = new CJS_KeyValue;
				pNewObjData->sKey = pOldObjData->sKey;
				pNewObjData->nType = pOldObjData->nType;
				pNewObjData->sData = pOldObjData->sData;
				Add(pNewObjData);
			}
			break;
		case JS_GLOBALDATA_TYPE_OBJECT:
			{
				CJS_KeyValue* pNewObjData = new CJS_KeyValue;
				pNewObjData->sKey = pOldObjData->sKey;
				pNewObjData->nType = pOldObjData->nType;
				pNewObjData->objData.Copy(pOldObjData->objData);
				Add(pNewObjData);
			}
		case JS_GLOBALDATA_TYPE_NULL:
			{
				CJS_KeyValue* pNewObjData = new CJS_KeyValue;
				pNewObjData->sKey = pOldObjData->sKey;
				pNewObjData->nType = pOldObjData->nType;
				Add(pNewObjData);
			}
		}
	}
}

void CJS_GlobalVariableArray::Add(CJS_KeyValue* p)
{
	array.Add(p);
}

int CJS_GlobalVariableArray::Count() const
{
	return array.GetSize();
}

CJS_KeyValue* CJS_GlobalVariableArray::GetAt(int index) const
{
	return array.GetAt(index);
}

void CJS_GlobalVariableArray::Empty()
{
	for (int i=0,sz=array.GetSize(); i<sz; i++)
		delete array.GetAt(i);
	array.RemoveAll();
}

/* -------------------------- CJS_GlobalData -------------------------- */

#define READER_JS_GLOBALDATA_FILENAME				L"Reader_JsGlobal.Data"
#define PHANTOM_JS_GLOBALDATA_FILENAME				L"Phantom_JsGlobal.Data"
#define SDK_JS_GLOBALDATA_FILENAME					L"SDK_JsGlobal.Data"

static const uint8_t JS_RC4KEY[] = {0x19,0xa8,0xe8,0x01,0xf6,0xa8,0xb6,0x4d,0x82,0x04,
							0x45,0x6d,0xb4,0xcf,0xd7,0x77,0x67,0xf9,0x75,0x9f,
							0xf0,0xe0,0x1e,0x51,0xee,0x46,0xfd,0x0b,0xc9,0x93,
							0x25,0x55,0x4a,0xee,0xe0,0x16,0xd0,0xdf,0x8c,0xfa,
							0x2a,0xa9,0x49,0xfd,0x97,0x1c,0x0e,0x22,0x13,0x28,
							0x7c,0xaf,0xc4,0xfc,0x9c,0x12,0x65,0x8c,0x4e,0x5b,
							0x04,0x75,0x89,0xc9,0xb1,0xed,0x50,0xca,0x96,0x6f,
							0x1a,0x7a,0xfe,0x58,0x5d,0xec,0x19,0x4a,0xf6,0x35,
							0x6a,0x97,0x14,0x00,0x0e,0xd0,0x6b,0xbb,0xd5,0x75,
							0x55,0x8b,0x6e,0x6b,0x19,0xa0,0xf8,0x77,0xd5,0xa3
							};

CJS_GlobalData::CJS_GlobalData(CPDFDoc_Environment* pApp)
{
// 	IBaseAnnot* pBaseAnnot = IBaseAnnot::GetBaseAnnot(m_pApp);
// 	ASSERT(pBaseAnnot != NULL);
//
// 	m_sFilePath = pBaseAnnot->GetUserPath();
	m_sFilePath += SDK_JS_GLOBALDATA_FILENAME;

	LoadGlobalPersistentVariables();
}

CJS_GlobalData::~CJS_GlobalData()
{
	SaveGlobalPersisitentVariables();

	for (int i=0,sz=m_arrayGlobalData.GetSize(); i<sz; i++)
		delete m_arrayGlobalData.GetAt(i);

	m_arrayGlobalData.RemoveAll();
}

int	CJS_GlobalData::FindGlobalVariable(const FX_CHAR* propname)
{
	ASSERT(propname != NULL);

	int nRet = -1;

	for (int i=0,sz=m_arrayGlobalData.GetSize(); i<sz; i++)
	{
		CJS_GlobalData_Element* pTemp = m_arrayGlobalData.GetAt(i);
		if (pTemp->data.sKey[0] == *propname && pTemp->data.sKey == propname)
		{
			nRet = i;
			break;
		}
	}

	return nRet;
}

CJS_GlobalData_Element* CJS_GlobalData::GetGlobalVariable(const FX_CHAR* propname)
{
	ASSERT(propname != NULL);

	int	nFind = FindGlobalVariable(propname);

	if (nFind >= 0)
		return m_arrayGlobalData.GetAt(nFind);
	else
		return NULL;
}

void CJS_GlobalData::SetGlobalVariableNumber(const FX_CHAR* propname, double dData)
{
	ASSERT(propname != NULL);
	CFX_ByteString sPropName = propname;

	sPropName.TrimLeft();
	sPropName.TrimRight();

	if (sPropName.GetLength() == 0) return;

	if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
	{
		pData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
		pData->data.dData = dData;
	}
	else
	{
		CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
		pNewData->data.sKey = sPropName;
		pNewData->data.nType = JS_GLOBALDATA_TYPE_NUMBER;
		pNewData->data.dData = dData;

		m_arrayGlobalData.Add(pNewData);
	}
}

void CJS_GlobalData::SetGlobalVariableBoolean(const FX_CHAR* propname, bool bData)
{
	ASSERT(propname != NULL);
	CFX_ByteString sPropName = propname;

	sPropName.TrimLeft();
	sPropName.TrimRight();

	if (sPropName.GetLength() == 0) return;

	if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
	{
		pData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
		pData->data.bData = bData;
	}
	else
	{
		CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
		pNewData->data.sKey = sPropName;
		pNewData->data.nType = JS_GLOBALDATA_TYPE_BOOLEAN;
		pNewData->data.bData = bData;

		m_arrayGlobalData.Add(pNewData);
	}
}

void CJS_GlobalData::SetGlobalVariableString(const FX_CHAR* propname, const CFX_ByteString& sData)
{
	ASSERT(propname != NULL);
	CFX_ByteString sPropName = propname;

	sPropName.TrimLeft();
	sPropName.TrimRight();

	if (sPropName.GetLength() == 0) return;

	if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
	{
		pData->data.nType = JS_GLOBALDATA_TYPE_STRING;
		pData->data.sData = sData;
	}
	else
	{
		CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
		pNewData->data.sKey = sPropName;
		pNewData->data.nType = JS_GLOBALDATA_TYPE_STRING;
		pNewData->data.sData = sData;

		m_arrayGlobalData.Add(pNewData);
	}
}

void CJS_GlobalData::SetGlobalVariableObject(const FX_CHAR* propname, const CJS_GlobalVariableArray& array)
{
	ASSERT(propname != NULL);
	CFX_ByteString sPropName = propname;

	sPropName.TrimLeft();
	sPropName.TrimRight();

	if (sPropName.GetLength() == 0) return;

	if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
	{
		pData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
		pData->data.objData.Copy(array);
	}
	else
	{
		CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
		pNewData->data.sKey = sPropName;
		pNewData->data.nType = JS_GLOBALDATA_TYPE_OBJECT;
		pNewData->data.objData.Copy(array);

		m_arrayGlobalData.Add(pNewData);
	}
}

void CJS_GlobalData::SetGlobalVariableNull(const FX_CHAR* propname)
{
	ASSERT(propname != NULL);
	CFX_ByteString sPropName = propname;

	sPropName.TrimLeft();
	sPropName.TrimRight();

	if (sPropName.GetLength() == 0) return;

	if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
	{
		pData->data.nType = JS_GLOBALDATA_TYPE_NULL;
	}
	else
	{
		CJS_GlobalData_Element* pNewData = new CJS_GlobalData_Element;
		pNewData->data.sKey = sPropName;
		pNewData->data.nType = JS_GLOBALDATA_TYPE_NULL;

		m_arrayGlobalData.Add(pNewData);
	}
}

FX_BOOL CJS_GlobalData::SetGlobalVariablePersistent(const FX_CHAR* propname, FX_BOOL bPersistent)
{
	ASSERT(propname != NULL);
	CFX_ByteString sPropName = propname;

	sPropName.TrimLeft();
	sPropName.TrimRight();

	if (sPropName.GetLength() == 0) return FALSE;

	if (CJS_GlobalData_Element* pData = GetGlobalVariable(sPropName))
	{
		pData->bPersistent = bPersistent;
		return TRUE;
	}

	return FALSE;
}

FX_BOOL CJS_GlobalData::DeleteGlobalVariable(const FX_CHAR* propname)
{
	ASSERT(propname != NULL);
	CFX_ByteString sPropName = propname;

	sPropName.TrimLeft();
	sPropName.TrimRight();

	if (sPropName.GetLength() == 0) return FALSE;

	int	nFind = FindGlobalVariable(sPropName);

	if (nFind >= 0)
	{
		delete m_arrayGlobalData.GetAt(nFind);
		m_arrayGlobalData.RemoveAt(nFind);
		return TRUE;
	}

	return FALSE;
}

int32_t CJS_GlobalData::GetSize() const
{
	return m_arrayGlobalData.GetSize();
}

CJS_GlobalData_Element* CJS_GlobalData::GetAt(int index) const
{
	return m_arrayGlobalData.GetAt(index);
}

void CJS_GlobalData::LoadGlobalPersistentVariables()
{
	uint8_t* pBuffer = NULL;
	int32_t nLength = 0;

	LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength);
	CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY));

	if (pBuffer)
	{
		uint8_t* p = pBuffer;
		FX_WORD wType = *((FX_WORD*)p);
		p += sizeof(FX_WORD);

		//FX_WORD wTemp = (FX_WORD)(('X' << 8) | 'F');

		if (wType == (FX_WORD)(('X' << 8) | 'F'))
		{
			FX_WORD wVersion = *((FX_WORD*)p);
			p += sizeof(FX_WORD);

			ASSERT(wVersion <= 2);

			FX_DWORD dwCount = *((FX_DWORD*)p);
			p += sizeof(FX_DWORD);

			FX_DWORD dwSize = *((FX_DWORD*)p);
			p += sizeof(FX_DWORD);

			if (dwSize == nLength - sizeof(FX_WORD) * 2 - sizeof(FX_DWORD)* 2)
			{
				for (int32_t i=0,sz=dwCount; i<sz; i++)
				{
					if (p > pBuffer + nLength)
						break;

					FX_DWORD dwNameLen = *((FX_DWORD*)p);
					p += sizeof(FX_DWORD);

					if (p + dwNameLen > pBuffer + nLength)
						break;

					CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen);
					p += sizeof(char) * dwNameLen;

					FX_WORD wDataType = *((FX_WORD*)p);
					p += sizeof(FX_WORD);

					switch (wDataType)
					{
					case JS_GLOBALDATA_TYPE_NUMBER:
						{
							double dData = 0;
							switch (wVersion)
							{
							case 1:
								{
									FX_DWORD dwData = *((FX_DWORD*)p);
									p += sizeof(FX_DWORD);
									dData = dwData;
								}
								break;
							case 2:
								{
									dData = *((double*)p);
									p += sizeof(double);
								}
								break;
							}
							SetGlobalVariableNumber(sEntry, dData);
							SetGlobalVariablePersistent(sEntry, TRUE);
						}
						break;
					case JS_GLOBALDATA_TYPE_BOOLEAN:
						{
							FX_WORD wData = *((FX_WORD*)p);
							p += sizeof(FX_WORD);
							SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
							SetGlobalVariablePersistent(sEntry, TRUE);
						}
						break;
					case JS_GLOBALDATA_TYPE_STRING:
						{
							FX_DWORD dwLength = *((FX_DWORD*)p);
							p += sizeof(FX_DWORD);

							if (p + dwLength > pBuffer + nLength)
								break;

							SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength));
							SetGlobalVariablePersistent(sEntry, TRUE);
							p += sizeof(char) * dwLength;
						}
						break;
					case JS_GLOBALDATA_TYPE_NULL:
						{
							SetGlobalVariableNull(sEntry);
							SetGlobalVariablePersistent(sEntry, TRUE);
						}
					}
				}
			}
		}
		FX_Free(pBuffer);
	}
}

/*
struct js_global_datafile_header
{
	FX_WORD type; //FX ('X' << 8) | 'F'
	FX_WORD version; //1.0
	FX_DWORD datacount;
};
struct js_global_datafile_data
{
	FX_WORD type;
	FX_DWORD nData;
	FX_WORD bData;
	FX_DWORD nStrLen;
	char* pStr;
};
*/

void CJS_GlobalData::SaveGlobalPersisitentVariables()
{
	FX_DWORD nCount = 0;
	CFX_BinaryBuf sData;

	for (int i=0,sz=m_arrayGlobalData.GetSize(); i<sz; i++)
	{
		CJS_GlobalData_Element* pElement = m_arrayGlobalData.GetAt(i);
		ASSERT(pElement != NULL);

		if (pElement->bPersistent)
		{
			CFX_BinaryBuf sElement;
			MakeByteString(pElement->data.sKey, &pElement->data, sElement);

			if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA)
				break;

			sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize());
			nCount++;
		}
	}

	CFX_BinaryBuf sFile;

	FX_WORD wType = (FX_WORD)(('X' << 8) | 'F');
	sFile.AppendBlock(&wType, sizeof(FX_WORD));
	FX_WORD wVersion = 2;
	sFile.AppendBlock(&wVersion, sizeof(FX_WORD));
	sFile.AppendBlock(&nCount, sizeof(FX_DWORD));
	FX_DWORD dwSize = sData.GetSize();
	sFile.AppendBlock(&dwSize, sizeof(FX_DWORD));

	sFile.AppendBlock(sData.GetBuffer(), sData.GetSize());

	CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY, sizeof(JS_RC4KEY));
	WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(), sFile.GetSize());
}

void CJS_GlobalData::LoadFileBuffer(const FX_WCHAR* sFilePath, uint8_t*& pBuffer, int32_t& nLength)
{
//UnSupport.
}

void CJS_GlobalData::WriteFileBuffer(const FX_WCHAR* sFilePath, const FX_CHAR* pBuffer, int32_t nLength)
{
//UnSupport.
}

void CJS_GlobalData::MakeByteString(const CFX_ByteString& name, CJS_KeyValue* pData, CFX_BinaryBuf& sData)
{
	ASSERT(pData != NULL);

	FX_WORD wType = (FX_WORD)pData->nType;

	switch (wType)
	{
	case JS_GLOBALDATA_TYPE_NUMBER:
		{
			FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
			sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
			sData.AppendString(name);

			sData.AppendBlock(&wType, sizeof(FX_WORD));
			double dData = pData->dData;
			sData.AppendBlock(&dData, sizeof(double));
		}
		break;
	case JS_GLOBALDATA_TYPE_BOOLEAN:
		{
			FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
			sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
			sData.AppendString(name);

			sData.AppendBlock(&wType, sizeof(FX_WORD));
			FX_WORD wData = (FX_WORD)pData->bData;
			sData.AppendBlock(&wData, sizeof(FX_WORD));
		}
		break;
	case JS_GLOBALDATA_TYPE_STRING:
		{
			FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
			sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
			sData.AppendString(name);

			sData.AppendBlock(&wType, sizeof(FX_WORD));

			FX_DWORD dwDataLen = (FX_DWORD)pData->sData.GetLength();
			sData.AppendBlock(&dwDataLen, sizeof(FX_DWORD));
			sData.AppendString(pData->sData);
		}
		break;
	case JS_GLOBALDATA_TYPE_NULL:
		{
			FX_DWORD dwNameLen = (FX_DWORD)name.GetLength();
			sData.AppendBlock(&dwNameLen, sizeof(FX_DWORD));
			sData.AppendString(name);

			sData.AppendBlock(&wType, sizeof(FX_DWORD));
		}
		break;
	default:
		break;
	}
}

