// 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/fpdfxfa/fpdfxfa_app.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();
	CPDFXFA_App::GetInstance()->GetRuntimeFactory()->ReleaseGlobalData();
}

void global_alternate::Initial(CPDFDoc_Environment* pApp)
{
	m_pApp = pApp;
	m_pGlobalData = CPDFXFA_App::GetInstance()->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:
            break;
        }
    }
    else
    {
        void* pVoid = nullptr;
        if (!m_mapGlobal.Lookup(CFX_ByteString::FromUnicode(propname), pVoid))
        {
            vp.SetNull();
            return TRUE;
        }
        if (!pVoid)
        {
            vp.SetNull();
            return TRUE;
        }
        js_global_data* pData = (js_global_data*)pVoid;
        if (pData->bDeleted)
            return TRUE;

        switch (pData->nType)
        {
            case JS_GLOBALDATA_TYPE_NUMBER:
                vp << pData->dData;
                return TRUE;
            case JS_GLOBALDATA_TYPE_BOOLEAN:
                vp << pData->bData;
                return TRUE;
            case JS_GLOBALDATA_TYPE_STRING:
                vp << pData->sData;
                return TRUE;
            case JS_GLOBALDATA_TYPE_OBJECT:
                {
                    v8::Local<v8::Object> obj = v8::Local<v8::Object>::New(vp.GetIsolate(),pData->pData);
                    vp << obj;
                    return TRUE;
                }
            case JS_GLOBALDATA_TYPE_NULL:
                vp.SetNull();
                return TRUE;
            default:
                break;
        }
    }
    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;
}
