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

#include <utility>

#include "core/fdrm/fx_crypt.h"
#include "core/fxcrt/stl_util.h"
#include "third_party/base/numerics/safe_conversions.h"

namespace {

constexpr size_t kMinGlobalDataBytes = 12;
constexpr size_t kMaxGlobalDataBytes = 4 * 1024 - 8;
constexpr uint16_t kMagic = ('X' << 8) | 'F';
constexpr uint16_t kMaxVersion = 2;

const uint8_t kRC4KEY[] = {
    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};

CFX_GlobalData* g_pInstance = nullptr;

// Returns true if non-empty, setting sPropName
bool TrimPropName(ByteString* sPropName) {
  sPropName->Trim();
  return sPropName->GetLength() != 0;
}

void MakeNameTypeString(const ByteString& name,
                        CFX_Value::DataType eType,
                        CFX_BinaryBuf* result) {
  uint32_t dwNameLen = (uint32_t)name.GetLength();
  result->AppendBlock(&dwNameLen, sizeof(uint32_t));
  result->AppendString(name);

  uint16_t wType = static_cast<uint16_t>(eType);
  result->AppendBlock(&wType, sizeof(uint16_t));
}

bool MakeByteString(const ByteString& name,
                    const CFX_KeyValue& pData,
                    CFX_BinaryBuf* result) {
  switch (pData.nType) {
    case CFX_Value::DataType::kNumber: {
      MakeNameTypeString(name, pData.nType, result);
      double dData = pData.dData;
      result->AppendBlock(&dData, sizeof(double));
      return true;
    }
    case CFX_Value::DataType::kBoolean: {
      MakeNameTypeString(name, pData.nType, result);
      uint16_t wData = static_cast<uint16_t>(pData.bData);
      result->AppendBlock(&wData, sizeof(uint16_t));
      return true;
    }
    case CFX_Value::DataType::kString: {
      MakeNameTypeString(name, pData.nType, result);
      uint32_t dwDataLen = (uint32_t)pData.sData.GetLength();
      result->AppendBlock(&dwDataLen, sizeof(uint32_t));
      result->AppendString(pData.sData);
      return true;
    }
    case CFX_Value::DataType::kNull: {
      MakeNameTypeString(name, pData.nType, result);
      return true;
    }
    // Arrays don't get persisted per JS spec page 484.
    case CFX_Value::DataType::kObject:
    default:
      break;
  }
  return false;
}

}  // namespace

// static
CFX_GlobalData* CFX_GlobalData::GetRetainedInstance(Delegate* pDelegate) {
  if (!g_pInstance) {
    g_pInstance = new CFX_GlobalData(pDelegate);
  }
  ++g_pInstance->m_RefCount;
  return g_pInstance;
}

bool CFX_GlobalData::Release() {
  if (--m_RefCount)
    return false;

  delete g_pInstance;
  g_pInstance = nullptr;
  return true;
}

CFX_GlobalData::CFX_GlobalData(Delegate* pDelegate) : m_pDelegate(pDelegate) {
  LoadGlobalPersistentVariables();
}

CFX_GlobalData::~CFX_GlobalData() {
  SaveGlobalPersisitentVariables();
}

CFX_GlobalData::iterator CFX_GlobalData::FindGlobalVariable(
    const ByteString& propname) {
  for (auto it = m_arrayGlobalData.begin(); it != m_arrayGlobalData.end();
       ++it) {
    if ((*it)->data.sKey == propname)
      return it;
  }
  return m_arrayGlobalData.end();
}

CFX_GlobalData::Element* CFX_GlobalData::GetGlobalVariable(
    const ByteString& propname) {
  auto iter = FindGlobalVariable(propname);
  return iter != m_arrayGlobalData.end() ? iter->get() : nullptr;
}

void CFX_GlobalData::SetGlobalVariableNumber(ByteString sPropName,
                                             double dData) {
  if (!TrimPropName(&sPropName))
    return;

  CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
  if (pData) {
    pData->data.nType = CFX_Value::DataType::kNumber;
    pData->data.dData = dData;
    return;
  }
  auto pNewData = std::make_unique<CFX_GlobalData::Element>();
  pNewData->data.sKey = std::move(sPropName);
  pNewData->data.nType = CFX_Value::DataType::kNumber;
  pNewData->data.dData = dData;
  m_arrayGlobalData.push_back(std::move(pNewData));
}

void CFX_GlobalData::SetGlobalVariableBoolean(ByteString sPropName,
                                              bool bData) {
  if (!TrimPropName(&sPropName))
    return;

  CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
  if (pData) {
    pData->data.nType = CFX_Value::DataType::kBoolean;
    pData->data.bData = bData;
    return;
  }
  auto pNewData = std::make_unique<CFX_GlobalData::Element>();
  pNewData->data.sKey = std::move(sPropName);
  pNewData->data.nType = CFX_Value::DataType::kBoolean;
  pNewData->data.bData = bData;
  m_arrayGlobalData.push_back(std::move(pNewData));
}

void CFX_GlobalData::SetGlobalVariableString(ByteString sPropName,
                                             const ByteString& sData) {
  if (!TrimPropName(&sPropName))
    return;

  CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
  if (pData) {
    pData->data.nType = CFX_Value::DataType::kString;
    pData->data.sData = sData;
    return;
  }
  auto pNewData = std::make_unique<CFX_GlobalData::Element>();
  pNewData->data.sKey = std::move(sPropName);
  pNewData->data.nType = CFX_Value::DataType::kString;
  pNewData->data.sData = sData;
  m_arrayGlobalData.push_back(std::move(pNewData));
}

void CFX_GlobalData::SetGlobalVariableObject(
    ByteString sPropName,
    std::vector<std::unique_ptr<CFX_KeyValue>> array) {
  if (!TrimPropName(&sPropName))
    return;

  CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
  if (pData) {
    pData->data.nType = CFX_Value::DataType::kObject;
    pData->data.objData = std::move(array);
    return;
  }
  auto pNewData = std::make_unique<CFX_GlobalData::Element>();
  pNewData->data.sKey = std::move(sPropName);
  pNewData->data.nType = CFX_Value::DataType::kObject;
  pNewData->data.objData = std::move(array);
  m_arrayGlobalData.push_back(std::move(pNewData));
}

void CFX_GlobalData::SetGlobalVariableNull(ByteString sPropName) {
  if (!TrimPropName(&sPropName))
    return;

  CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
  if (pData) {
    pData->data.nType = CFX_Value::DataType::kNull;
    return;
  }
  auto pNewData = std::make_unique<CFX_GlobalData::Element>();
  pNewData->data.sKey = std::move(sPropName);
  pNewData->data.nType = CFX_Value::DataType::kNull;
  m_arrayGlobalData.push_back(std::move(pNewData));
}

bool CFX_GlobalData::SetGlobalVariablePersistent(ByteString sPropName,
                                                 bool bPersistent) {
  if (!TrimPropName(&sPropName))
    return false;

  CFX_GlobalData::Element* pData = GetGlobalVariable(sPropName);
  if (!pData)
    return false;

  pData->bPersistent = bPersistent;
  return true;
}

bool CFX_GlobalData::DeleteGlobalVariable(ByteString sPropName) {
  if (!TrimPropName(&sPropName))
    return false;

  auto iter = FindGlobalVariable(sPropName);
  if (iter == m_arrayGlobalData.end())
    return false;

  m_arrayGlobalData.erase(iter);
  return true;
}

int32_t CFX_GlobalData::GetSize() const {
  return fxcrt::CollectionSize<int32_t>(m_arrayGlobalData);
}

CFX_GlobalData::Element* CFX_GlobalData::GetAt(int index) {
  if (index < 0 || index >= GetSize())
    return nullptr;
  return m_arrayGlobalData[index].get();
}

bool CFX_GlobalData::LoadGlobalPersistentVariables() {
  if (!m_pDelegate)
    return false;

  bool ret;
  {
    // Span can't outlive call to BufferDone().
    absl::optional<pdfium::span<uint8_t>> buffer = m_pDelegate->LoadBuffer();
    if (!buffer.has_value() || buffer.value().empty())
      return false;

    ret = LoadGlobalPersistentVariablesFromBuffer(buffer.value());
  }
  m_pDelegate->BufferDone();
  return ret;
}

bool CFX_GlobalData::LoadGlobalPersistentVariablesFromBuffer(
    pdfium::span<uint8_t> buffer) {
  if (buffer.size() < kMinGlobalDataBytes)
    return false;

  CRYPT_ArcFourCryptBlock(buffer, kRC4KEY);

  uint8_t* p = buffer.data();
  uint16_t wType = *((uint16_t*)p);
  p += sizeof(uint16_t);
  if (wType != kMagic)
    return false;

  uint16_t wVersion = *((uint16_t*)p);
  p += sizeof(uint16_t);
  if (wVersion > kMaxVersion)
    return false;

  uint32_t dwCount = *((uint32_t*)p);
  p += sizeof(uint32_t);

  uint32_t dwSize = *((uint32_t*)p);
  p += sizeof(uint32_t);

  if (dwSize != buffer.size() - sizeof(uint16_t) * 2 - sizeof(uint32_t) * 2)
    return false;

  for (int32_t i = 0, sz = dwCount; i < sz; i++) {
    if (p > buffer.end())
      break;

    uint32_t dwNameLen = *((uint32_t*)p);
    p += sizeof(uint32_t);
    if (p + dwNameLen > buffer.end())
      break;

    ByteString sEntry = ByteString(p, dwNameLen);
    p += sizeof(char) * dwNameLen;

    CFX_Value::DataType wDataType =
        static_cast<CFX_Value::DataType>(*((uint16_t*)p));
    p += sizeof(uint16_t);

    switch (wDataType) {
      case CFX_Value::DataType::kNumber: {
        double dData = 0;
        switch (wVersion) {
          case 1: {
            uint32_t dwData = *((uint32_t*)p);
            p += sizeof(uint32_t);
            dData = dwData;
          } break;
          case 2: {
            dData = *((double*)p);
            p += sizeof(double);
          } break;
        }
        SetGlobalVariableNumber(sEntry, dData);
        SetGlobalVariablePersistent(sEntry, true);
      } break;
      case CFX_Value::DataType::kBoolean: {
        uint16_t wData = *((uint16_t*)p);
        p += sizeof(uint16_t);
        SetGlobalVariableBoolean(sEntry, (bool)(wData == 1));
        SetGlobalVariablePersistent(sEntry, true);
      } break;
      case CFX_Value::DataType::kString: {
        uint32_t dwLength = *((uint32_t*)p);
        p += sizeof(uint32_t);
        if (p + dwLength > buffer.end())
          break;

        SetGlobalVariableString(sEntry, ByteString(p, dwLength));
        SetGlobalVariablePersistent(sEntry, true);
        p += sizeof(char) * dwLength;
      } break;
      case CFX_Value::DataType::kNull: {
        SetGlobalVariableNull(sEntry);
        SetGlobalVariablePersistent(sEntry, true);
      } break;
      case CFX_Value::DataType::kObject:
      default:
        // Arrays aren't allowed in these buffers, nor are unrecoginzed tags.
        return false;
    }
  }
  return true;
}

bool CFX_GlobalData::SaveGlobalPersisitentVariables() {
  if (!m_pDelegate)
    return false;

  uint32_t nCount = 0;
  CFX_BinaryBuf sData;
  for (const auto& pElement : m_arrayGlobalData) {
    if (!pElement->bPersistent)
      continue;

    CFX_BinaryBuf sElement;
    if (!MakeByteString(pElement->data.sKey, pElement->data, &sElement))
      continue;

    if (sData.GetSize() + sElement.GetSize() > kMaxGlobalDataBytes)
      break;

    sData.AppendSpan(sElement.GetSpan());
    nCount++;
  }

  CFX_BinaryBuf sFile;
  uint16_t wType = kMagic;
  uint16_t wVersion = 2;
  sFile.AppendBlock(&wType, sizeof(uint16_t));
  sFile.AppendBlock(&wVersion, sizeof(uint16_t));
  sFile.AppendBlock(&nCount, sizeof(uint32_t));

  uint32_t dwSize = pdfium::base::checked_cast<uint32_t>(sData.GetSize());
  sFile.AppendBlock(&dwSize, sizeof(uint32_t));
  sFile.AppendSpan(sData.GetSpan());

  CRYPT_ArcFourCryptBlock(sFile.GetSpan(), kRC4KEY);
  return m_pDelegate->StoreBuffer(sFile.GetSpan());
}

CFX_GlobalData::Element::Element() = default;

CFX_GlobalData::Element::~Element() = default;
