// 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,
                        BinaryBuffer* 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,
                    BinaryBuffer* 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;
  BinaryBuffer sData;
  for (const auto& pElement : m_arrayGlobalData) {
    if (!pElement->bPersistent)
      continue;

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

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

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

  BinaryBuffer 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.GetMutableSpan(), kRC4KEY);
  return m_pDelegate->StoreBuffer(sFile.GetSpan());
}

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

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