// 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 "../../../core/include/fdrm/fx_crypt.h"
#include "../../include/javascript/JavaScript.h"
#include "../../include/javascript/IJavaScript.h"
#include "../../include/javascript/JS_GlobalData.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(CPDFDoc_Environment* pApp) {
  //  IBaseAnnot* pBaseAnnot = IBaseAnnot::GetBaseAnnot(m_pApp);
  //  ASSERT(pBaseAnnot != NULL);
  //
  //  m_sFilePath = pBaseAnnot->GetUserPath();
  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) {
  ASSERT(propname != NULL);

  int nRet = -1;

  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) {
      nRet = i;
      break;
    }
  }

  return nRet;
}

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

/*
struct js_global_datafile_header
{
    FX_WORD type; //FX ('X' << 8) | 'F'
    FX_WORD version; //1.0
    FX_DWORD datacount;
};
struct js_global_datafile_data
{
    FX_WORD type;
    FX_DWORD nData;
    FX_WORD bData;
    FX_DWORD nStrLen;
    char* pStr;
};
*/

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