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

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

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

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

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

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


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