// 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 "../../include/javascript/IJavaScript.h"
#include "../../include/javascript/JS_Context.h"
#include "../../include/javascript/JS_Define.h"
#include "../../include/javascript/JS_EventHandler.h"
#include "../../include/javascript/JS_GlobalData.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
#include "../../include/javascript/JavaScript.h"
#include "../../include/javascript/global.h"
#include "../../include/javascript/resource.h"

/* ---------------------------- global ---------------------------- */

// Helper class for compile-time calculation of hash values in order to
// avoid having global object initializers.
template <unsigned ACC, wchar_t... Ns>
struct CHash;

// Only needed to hash single-character strings.
template <wchar_t N>
struct CHash<N> {
  static const unsigned value = N;
};

template <unsigned ACC, wchar_t N>
struct CHash<ACC, N> {
  static const unsigned value = (ACC * 1313LLU + N) & 0xFFFFFFFF;
};

template <unsigned ACC, wchar_t N, wchar_t... Ns>
struct CHash<ACC, N, Ns...> {
  static const unsigned value = CHash<CHash<ACC, N>::value, Ns...>::value;
};

extern const unsigned int JSCONST_nStringHash =
  CHash<'s','t','r','i','n','g'>::value;
extern const unsigned int JSCONST_nNumberHash =
  CHash<'n','u','m','b','e','r'>::value;
extern const unsigned int JSCONST_nBoolHash =
  CHash<'b','o','o','l','e','a','n'>::value;
extern const unsigned int JSCONST_nDateHash =
  CHash<'d','a','t','e'>::value;
extern const unsigned int JSCONST_nObjectHash =
  CHash<'o','b','j','e','c','t'>::value;
extern const unsigned int JSCONST_nFXobjHash =
  CHash<'f','x','o','b','j'>::value;
extern const unsigned int JSCONST_nNullHash =
  CHash<'n','u','l','l'>::value;
extern const unsigned int JSCONST_nUndefHash =
  CHash<'u','n','d','e','f','i','n','e','d'>::value;

#ifdef _DEBUG
class HashVerify
{
public:
  HashVerify();
} g_hashVerify;

HashVerify::HashVerify()
{
  ASSERT(JSCONST_nStringHash ==
    JS_CalcHash(VALUE_NAME_STRING,wcslen(VALUE_NAME_STRING)));
  ASSERT(JSCONST_nNumberHash ==
    JS_CalcHash(VALUE_NAME_NUMBER,wcslen(VALUE_NAME_NUMBER)));
  ASSERT(JSCONST_nBoolHash ==
    JS_CalcHash(VALUE_NAME_BOOLEAN,wcslen(VALUE_NAME_BOOLEAN)));
  ASSERT(JSCONST_nDateHash ==
    JS_CalcHash(VALUE_NAME_DATE,wcslen(VALUE_NAME_DATE)));
  ASSERT(JSCONST_nObjectHash ==
    JS_CalcHash(VALUE_NAME_OBJECT,wcslen(VALUE_NAME_OBJECT)));
  ASSERT(JSCONST_nFXobjHash ==
    JS_CalcHash(VALUE_NAME_FXOBJ,wcslen(VALUE_NAME_FXOBJ)));
  ASSERT(JSCONST_nNullHash ==
    JS_CalcHash(VALUE_NAME_NULL,wcslen(VALUE_NAME_NULL)));
  ASSERT(JSCONST_nUndefHash ==
    JS_CalcHash(VALUE_NAME_UNDEFINED,wcslen(VALUE_NAME_UNDEFINED)));
}
#endif


BEGIN_JS_STATIC_CONST(CJS_Global)
END_JS_STATIC_CONST()

BEGIN_JS_STATIC_PROP(CJS_Global)
END_JS_STATIC_PROP()

BEGIN_JS_STATIC_METHOD(CJS_Global)
	JS_STATIC_METHOD_ENTRY(setPersistent)
END_JS_STATIC_METHOD()

IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, global_alternate, global);

FX_BOOL	CJS_Global::InitInstance(IFXJS_Context* cc)
{
	CJS_Context* pContext = (CJS_Context*)cc;
	ASSERT(pContext != NULL);

	global_alternate* pGlobal = (global_alternate*)GetEmbedObject();
	ASSERT(pGlobal != NULL);

	pGlobal->Initial(pContext->GetReaderApp());

	return TRUE;
};

global_alternate::global_alternate(CJS_Object* pJSObject)
	: CJS_EmbedObj(pJSObject),
	m_pApp(NULL)
{
}

global_alternate::~global_alternate(void)
{
	DestroyGlobalPersisitentVariables();
	m_pApp->GetRuntimeFactory()->ReleaseGlobalData();
}

void global_alternate::Initial(CPDFDoc_Environment* pApp)
{
	m_pApp = pApp;
	m_pGlobalData = pApp->GetRuntimeFactory()->NewGlobalData(pApp);
	UpdateGlobalPersistentVariables();
}

FX_BOOL	global_alternate::QueryProperty(const FX_WCHAR* propname)
{
	return CFX_WideString(propname) != L"setPersistent";
}

FX_BOOL	global_alternate::DelProperty(IFXJS_Context* cc, const FX_WCHAR* propname, CFX_WideString& sError)
{
	js_global_data* pData = NULL;
	CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);

	if (m_mapGlobal.Lookup(sPropName, (void*&)pData))
	{
		pData->bDeleted = TRUE;
		return TRUE;
	}

	return FALSE;
}

FX_BOOL global_alternate::DoProperty(IFXJS_Context* cc, const FX_WCHAR* propname, CJS_PropValue& vp, CFX_WideString& sError)
{
	if (vp.IsSetting())
	{
		CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
		switch (vp.GetType())
		{
		case VT_number:
			{
				double dData;
				vp >> dData;
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NUMBER, dData, false, "", v8::Local<v8::Object>(), FALSE);
			}
		case VT_boolean:
			{
				bool bData;
				vp >> bData;
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_BOOLEAN, 0, bData, "", v8::Local<v8::Object>(), FALSE);
			}
		case VT_string:
			{
				CFX_ByteString sData;
				vp >> sData;
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_STRING, 0, false, sData, v8::Local<v8::Object>(), FALSE);
			}
		case VT_object:
			{
				JSObject pData;
				vp >> pData;
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "", pData, FALSE);
			}
		case VT_null:
			{
				return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NULL, 0, false, "", v8::Local<v8::Object>(), FALSE);
			}
		case VT_undefined:
			{
				DelProperty(cc, propname, sError);
				return TRUE;
			}
		default:
			return FALSE;
		}
	}
	else
	{
		js_global_data* pData = NULL;
		CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);

		if (m_mapGlobal.Lookup(sPropName, (void*&)pData))
		{
			if (pData)
			{
				if (!pData->bDeleted)
				{
					switch (pData->nType)
					{
					case JS_GLOBALDATA_TYPE_NUMBER:
						vp << pData->dData;
						break;
					case JS_GLOBALDATA_TYPE_BOOLEAN:
						vp << pData->bData;
						break;
					case JS_GLOBALDATA_TYPE_STRING:
						vp << pData->sData;
						break;
					case JS_GLOBALDATA_TYPE_OBJECT:
						{
							v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(vp.GetIsolate(),pData->pData);
							vp << obj;
							break;
						}
					case JS_GLOBALDATA_TYPE_NULL:
						vp.SetNull();
						break;
					default:
						return FALSE;
					}
					return TRUE;
				}
				else
				{
					return TRUE;
				}
			}
			else
			{
				vp.SetNull();
				return TRUE;
			}
		}
		else
		{
			vp.SetNull();
			return TRUE;
		}
	}

	return FALSE;
}

FX_BOOL global_alternate::setPersistent(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, CFX_WideString& sError)
{
	CJS_Context* pContext = static_cast<CJS_Context*>(cc);
	if (params.size() != 2)
	{
		sError = JSGetStringFromID(pContext, IDS_STRING_JSPARAMERROR);
		return FALSE;
	}

	CFX_ByteString sName = params[0].ToCFXByteString();

	js_global_data* pData = NULL;
	if (m_mapGlobal.Lookup(sName, (void*&)pData))
	{
		if (pData && !pData->bDeleted)
		{
			pData->bPersistent = params[1].ToBool();
			return TRUE;
		}
	}

	sError = JSGetStringFromID(pContext, IDS_STRING_JSNOGLOBAL);
	return FALSE;
}

void global_alternate::UpdateGlobalPersistentVariables()
{
	ASSERT(m_pGlobalData != NULL);

	for (int i=0,sz=m_pGlobalData->GetSize(); i<sz; i++)
	{
		CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i);
		ASSERT(pData != NULL);

		switch (pData->data.nType)
		{
		case JS_GLOBALDATA_TYPE_NUMBER:
			SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NUMBER, pData->data.dData, false, "", v8::Local<v8::Object>(), pData->bPersistent == 1);
			JS_PutObjectNumber(NULL,(JSFXObject)(*m_pJSObject),
							   pData->data.sKey.UTF8Decode().c_str(), pData->data.dData);
			break;
		case JS_GLOBALDATA_TYPE_BOOLEAN:
			SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_BOOLEAN, 0, (bool)(pData->data.bData == 1), "", v8::Local<v8::Object>(), pData->bPersistent == 1);
			JS_PutObjectBoolean(NULL,(JSFXObject)(*m_pJSObject),
								pData->data.sKey.UTF8Decode().c_str(), (bool)(pData->data.bData == 1));
			break;
		case JS_GLOBALDATA_TYPE_STRING:
			SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_STRING, 0, false, pData->data.sData, v8::Local<v8::Object>(), pData->bPersistent == 1);
			JS_PutObjectString(NULL, (JSFXObject)(*m_pJSObject),
							   pData->data.sKey.UTF8Decode().c_str(),
							   pData->data.sData.UTF8Decode().c_str());
			break;
		case JS_GLOBALDATA_TYPE_OBJECT:
			{
				IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
				v8::Local<v8::Object> pObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);

				PutObjectProperty(pObj, &pData->data);

				SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "",
					(JSObject)pObj, pData->bPersistent == 1);
				JS_PutObjectObject(NULL,(JSFXObject)(*m_pJSObject),
								   pData->data.sKey.UTF8Decode().c_str(), (JSObject)pObj);
			}
			break;
		case JS_GLOBALDATA_TYPE_NULL:
			SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NULL, 0, false, "", v8::Local<v8::Object>(), pData->bPersistent == 1);
			JS_PutObjectNull(NULL,(JSFXObject)(*m_pJSObject),
							 pData->data.sKey.UTF8Decode().c_str());
			break;
		}
	}
}

void global_alternate::CommitGlobalPersisitentVariables()
{
	ASSERT(m_pGlobalData != NULL);

	FX_POSITION	 pos = m_mapGlobal.GetStartPosition();
	while (pos)
	{
		CFX_ByteString name;
		js_global_data* pData = NULL;
		m_mapGlobal.GetNextAssoc(pos, name, (void*&)pData);

		if (pData)
		{
			if (pData->bDeleted)
			{
				m_pGlobalData->DeleteGlobalVariable(name);
			}
			else
			{
				switch (pData->nType)
				{
				case JS_GLOBALDATA_TYPE_NUMBER:
					m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
					m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					break;
				case JS_GLOBALDATA_TYPE_BOOLEAN:
					m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
					m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					break;
				case JS_GLOBALDATA_TYPE_STRING:
					m_pGlobalData->SetGlobalVariableString(name, pData->sData);
					m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					break;
				case JS_GLOBALDATA_TYPE_OBJECT:
					//if (pData->pData)
					{
						CJS_GlobalVariableArray array;
						v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(GetJSObject()->GetIsolate(),pData->pData);
						ObjectToArray(obj, array);
						m_pGlobalData->SetGlobalVariableObject(name, array);
						m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					}
					break;
				case JS_GLOBALDATA_TYPE_NULL:
					m_pGlobalData->SetGlobalVariableNull(name);
					m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
					break;
				}
			}
		}
	}
}

void global_alternate::ObjectToArray(v8::Local<v8::Object> pObj, CJS_GlobalVariableArray& array)
{
	v8::Local<v8::Context> context = pObj->CreationContext();
	v8::Isolate* isolate = context->GetIsolate();
	v8::Local<v8::Array> pKeyList = JS_GetObjectElementNames(isolate, pObj);
	int	nObjElements = pKeyList->Length();

	for (int i=0; i<nObjElements; i++)
	{

		CFX_WideString ws = JS_ToString(isolate, JS_GetArrayElement(isolate, pKeyList, i));
		CFX_ByteString sKey = ws.UTF8Encode();

		v8::Local<v8::Value> v = JS_GetObjectElement(isolate, pObj, ws.c_str());
		FXJSVALUETYPE vt = GET_VALUE_TYPE(v);
		switch (vt)
		{
		case VT_number:
			{
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_NUMBER;
				pObjElement->sKey = sKey;
				pObjElement->dData = JS_ToNumber(isolate, v);
				array.Add(pObjElement);
			}
			break;
		case VT_boolean:
			{
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
				pObjElement->sKey = sKey;
				pObjElement->dData = JS_ToBoolean(isolate, v);
				array.Add(pObjElement);
			}
			break;
		case VT_string:
			{
				CFX_ByteString sValue = CJS_Value(isolate, v, VT_string).ToCFXByteString();
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_STRING;
				pObjElement->sKey = sKey;
				pObjElement->sData = sValue;
				array.Add(pObjElement);
			}
			break;
		case VT_object:
			{
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_OBJECT;
				pObjElement->sKey = sKey;
				ObjectToArray(JS_ToObject(isolate, v), pObjElement->objData);
				array.Add(pObjElement);
			}
			break;
		case VT_null:
			{
				CJS_KeyValue* pObjElement = new CJS_KeyValue;
				pObjElement->nType = JS_GLOBALDATA_TYPE_NULL;
				pObjElement->sKey = sKey;
				array.Add(pObjElement);
			}
			break;
		default:
			break;
		}
	}
}

void global_alternate::PutObjectProperty(v8::Local<v8::Object> pObj, CJS_KeyValue* pData)
{
	ASSERT(pData != NULL);

	for (int i=0,sz=pData->objData.Count(); i<sz; i++)
	{
		CJS_KeyValue* pObjData = pData->objData.GetAt(i);
		ASSERT(pObjData != NULL);

		switch (pObjData->nType)
		{
		case JS_GLOBALDATA_TYPE_NUMBER:
			JS_PutObjectNumber(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), pObjData->dData);
			break;
		case JS_GLOBALDATA_TYPE_BOOLEAN:
			JS_PutObjectBoolean(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), (bool)(pObjData->bData == 1));
			break;
		case JS_GLOBALDATA_TYPE_STRING:
			JS_PutObjectString(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), pObjData->sData.UTF8Decode().c_str());
			break;
		case JS_GLOBALDATA_TYPE_OBJECT:
			{
				IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
				v8::Local<v8::Object> pNewObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);
				PutObjectProperty(pNewObj, pObjData);
				JS_PutObjectObject(NULL, (JSObject)pObj, pObjData->sKey.UTF8Decode().c_str(), (JSObject)pNewObj);
			}
			break;
		case JS_GLOBALDATA_TYPE_NULL:
			JS_PutObjectNull(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode().c_str());
			break;
		}
	}
}

void global_alternate::DestroyGlobalPersisitentVariables()
{
	FX_POSITION	 pos = m_mapGlobal.GetStartPosition();
	while (pos)
	{
		CFX_ByteString name;
		js_global_data* pData = NULL;
		m_mapGlobal.GetNextAssoc(pos, name, (void*&)pData);
		delete pData;
	}

	m_mapGlobal.RemoveAll();
}


FX_BOOL global_alternate::SetGlobalVariables(const FX_CHAR* propname, int nType,
				double dData, bool bData, const CFX_ByteString& sData, JSObject pData, bool bDefaultPersistent)
{
	if (propname == NULL) return FALSE;

	js_global_data* pTemp = NULL;
	m_mapGlobal.Lookup(propname, (void*&)pTemp);

	if (pTemp)
	{
		if (pTemp->bDeleted || pTemp->nType != nType)
		{
			pTemp->dData = 0;
			pTemp->bData = 0;
			pTemp->sData = "";
			pTemp->nType = nType;
		}

		pTemp->bDeleted = FALSE;

		switch (nType)
		{
		case JS_GLOBALDATA_TYPE_NUMBER:
			{
				pTemp->dData = dData;
			}
			break;
		case JS_GLOBALDATA_TYPE_BOOLEAN:
			{
				pTemp->bData = bData;
			}
			break;
		case JS_GLOBALDATA_TYPE_STRING:
			{
				pTemp->sData = sData;
			}
			break;
		case JS_GLOBALDATA_TYPE_OBJECT:
			{
				pTemp->pData.Reset(JS_GetRuntime(pData), pData);
			}
			break;
		case JS_GLOBALDATA_TYPE_NULL:
			break;
		default:
			return FALSE;
		}

		return TRUE;
	}

	js_global_data* pNewData = NULL;

	switch (nType)
	{
	case JS_GLOBALDATA_TYPE_NUMBER:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_NUMBER;
			pNewData->dData = dData;
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	case JS_GLOBALDATA_TYPE_BOOLEAN:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
			pNewData->bData = bData;
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	case JS_GLOBALDATA_TYPE_STRING:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_STRING;
			pNewData->sData = sData;
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	case JS_GLOBALDATA_TYPE_OBJECT:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_OBJECT;
			pNewData->pData.Reset(JS_GetRuntime(pData), pData);
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	case JS_GLOBALDATA_TYPE_NULL:
		{
			pNewData = new js_global_data;
			pNewData->nType = JS_GLOBALDATA_TYPE_NULL;
			pNewData->bPersistent = bDefaultPersistent;
		}
		break;
	default:
		return FALSE;
	}

	m_mapGlobal.SetAt(propname, (void*)pNewData);

	return TRUE;
}

FXJSVALUETYPE GET_VALUE_TYPE(v8::Local<v8::Value> p)
{
  const unsigned int nHash = JS_CalcHash(JS_GetTypeof(p));

  if (nHash == JSCONST_nUndefHash)
    return VT_undefined;
  if (nHash == JSCONST_nNullHash)
    return VT_null;
  if (nHash == JSCONST_nStringHash)
    return VT_string;
  if (nHash == JSCONST_nNumberHash)
    return VT_number;
  if (nHash == JSCONST_nBoolHash)
    return VT_boolean;
  if (nHash == JSCONST_nDateHash)
    return VT_date;
  if (nHash == JSCONST_nObjectHash)
    return VT_object;
  if (nHash == JSCONST_nFXobjHash)
    return VT_fxobject;

  return VT_unknown;
}

