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

  int nFind = FindGlobalVariable(propname);
  return nFind >= 0 ? m_arrayGlobalData.GetAt(nFind) : nullptr;
}

void CJS_GlobalData::SetGlobalVariableNumber(const FX_CHAR* propname,
                                             double dData) {
  ASSERT(propname);
  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);
  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);
  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);
  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);
  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);
  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);
  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);
    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;
  }
}
