// 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 "JS_GlobalData.h"

#include "../../../core/include/fdrm/fx_crypt.h"
#include "../../include/javascript/IJavaScript.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::g_Instance = nullptr;

// static
CJS_GlobalData* CJS_GlobalData::GetRetainedInstance(CPDFDoc_Environment* pApp) {
  if (!g_Instance) {
    g_Instance = new CJS_GlobalData();
  }
  ++g_Instance->m_RefCount;
  return g_Instance;
}

void CJS_GlobalData::Release() {
  if (!--m_RefCount) {
    delete g_Instance;
    g_Instance = nullptr;
  }
}

CJS_GlobalData::CJS_GlobalData() : m_RefCount(0) {
  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) {
  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)
      return i;
  }
  return -1;
}

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

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

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