// 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);
      } break;
      case JS_GLOBALDATA_TYPE_NULL: {
        CJS_KeyValue* pNewObjData = new CJS_KeyValue;
        pNewObjData->sKey = pOldObjData->sKey;
        pNewObjData->nType = pOldObjData->nType;
        Add(pNewObjData);
      } break;
    }
  }
}

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