// Copyright 2016 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/fpdfapi/parser/cpdf_indirect_object_holder.h"

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_object.h"
#include "core/fpdfapi/parser/cpdf_parser.h"
#include "core/fpdfapi/parser/cpdf_stream.h"

CPDF_IndirectObjectHolder::CPDF_IndirectObjectHolder() : m_LastObjNum(0) {}

CPDF_IndirectObjectHolder::~CPDF_IndirectObjectHolder() {}

CPDF_Object* CPDF_IndirectObjectHolder::GetIndirectObject(
    uint32_t objnum) const {
  auto it = m_IndirectObjs.find(objnum);
  return it != m_IndirectObjs.end() ? it->second.get() : nullptr;
}

CPDF_Object* CPDF_IndirectObjectHolder::GetOrParseIndirectObject(
    uint32_t objnum) {
  if (objnum == 0)
    return nullptr;

  CPDF_Object* pObj = GetIndirectObject(objnum);
  if (pObj)
    return pObj->GetObjNum() != CPDF_Object::kInvalidObjNum ? pObj : nullptr;

  pObj = ParseIndirectObject(objnum);
  if (!pObj)
    return nullptr;

  pObj->m_ObjNum = objnum;
  m_LastObjNum = std::max(m_LastObjNum, objnum);
  m_IndirectObjs[objnum].reset(pObj);
  return pObj;
}

CPDF_Object* CPDF_IndirectObjectHolder::ParseIndirectObject(uint32_t objnum) {
  return nullptr;
}

CPDF_Object* CPDF_IndirectObjectHolder::AddIndirectObject(UniqueObject pObj) {
  if (pObj->m_ObjNum)
    return pObj.release();  // TODO(tsepez): shouldn't happen, stop this leak.

  pObj->m_ObjNum = ++m_LastObjNum;
  m_IndirectObjs[m_LastObjNum].release();  // TODO(tsepez): stop this leak.
  m_IndirectObjs[m_LastObjNum].reset(pObj.release());  // Changes deleters.
  return m_IndirectObjs[m_LastObjNum].get();
}

CPDF_Array* CPDF_IndirectObjectHolder::AddIndirectArray() {
  return ToArray(AddIndirectObject(UniqueObject(new CPDF_Array())));
}

CPDF_Dictionary* CPDF_IndirectObjectHolder::AddIndirectDictionary() {
  return ToDictionary(AddIndirectObject(UniqueObject(new CPDF_Dictionary())));
}

CPDF_Dictionary* CPDF_IndirectObjectHolder::AddIndirectDictionary(
    const CFX_WeakPtr<CFX_ByteStringPool>& pPool) {
  return ToDictionary(
      AddIndirectObject(UniqueObject(new CPDF_Dictionary(pPool))));
}

CPDF_Stream* CPDF_IndirectObjectHolder::AddIndirectStream() {
  return ToStream(AddIndirectObject(UniqueObject(new CPDF_Stream())));
}

CPDF_Stream* CPDF_IndirectObjectHolder::AddIndirectStream(
    uint8_t* pData,
    uint32_t size,
    CPDF_Dictionary* pDict) {
  return ToStream(
      AddIndirectObject(UniqueObject(new CPDF_Stream(pData, size, pDict))));
}

bool CPDF_IndirectObjectHolder::ReplaceIndirectObjectIfHigherGeneration(
    uint32_t objnum,
    UniqueObject pObj) {
  if (!objnum || !pObj)
    return false;

  CPDF_Object* pOldObj = GetIndirectObject(objnum);
  if (pOldObj && pObj->GetGenNum() <= pOldObj->GetGenNum())
    return false;

  pObj->m_ObjNum = objnum;
  m_IndirectObjs[objnum].reset(pObj.release());  // Changes deleters.
  m_LastObjNum = std::max(m_LastObjNum, objnum);
  return true;
}

void CPDF_IndirectObjectHolder::DeleteIndirectObject(uint32_t objnum) {
  CPDF_Object* pObj = GetIndirectObject(objnum);
  if (!pObj || pObj->GetObjNum() == CPDF_Object::kInvalidObjNum)
    return;

  m_IndirectObjs.erase(objnum);
}
