// Copyright 2018 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.

#ifndef CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_TABLE_H_
#define CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_TABLE_H_

#include <stdint.h>

#include <map>
#include <memory>

#include "core/fxcrt/fx_types.h"
#include "core/fxcrt/retain_ptr.h"

class CPDF_Dictionary;

class CPDF_CrossRefTable {
 public:
  enum class ObjectType : uint8_t {
    kFree = 0x00,
    kNormal = 0x01,
    kNotCompressed = kNormal,
    kCompressed = 0x02,
    kObjStream = 0xFF,
    kNull = kObjStream,
  };

  struct ObjectInfo {
    ObjectInfo() : pos(0), type(ObjectType::kFree), gennum(0) {}
    // if type is ObjectType::kCompressed the archive_obj_num should be used.
    // if type is ObjectType::kNotCompressed the pos should be used.
    // In other cases its are unused.
    union {
      FX_FILESIZE pos;
      uint32_t archive_obj_num;
    };
    ObjectType type;
    uint16_t gennum;
  };

  // Merge cross reference tables.  Apply top on current.
  static std::unique_ptr<CPDF_CrossRefTable> MergeUp(
      std::unique_ptr<CPDF_CrossRefTable> current,
      std::unique_ptr<CPDF_CrossRefTable> top);

  CPDF_CrossRefTable();
  explicit CPDF_CrossRefTable(RetainPtr<CPDF_Dictionary> trailer);
  ~CPDF_CrossRefTable();

  void AddCompressed(uint32_t obj_num, uint32_t archive_obj_num);
  void AddNormal(uint32_t obj_num, uint16_t gen_num, FX_FILESIZE pos);
  void SetFree(uint32_t obj_num);

  void SetTrailer(RetainPtr<CPDF_Dictionary> trailer);
  const CPDF_Dictionary* trailer() const { return trailer_.Get(); }
  CPDF_Dictionary* GetMutableTrailerForTesting() { return trailer_.Get(); }

  const ObjectInfo* GetObjectInfo(uint32_t obj_num) const;

  const std::map<uint32_t, ObjectInfo>& objects_info() const {
    return objects_info_;
  }

  void Update(std::unique_ptr<CPDF_CrossRefTable> new_cross_ref);

  void ShrinkObjectMap(uint32_t objnum);

 private:
  void UpdateInfo(std::map<uint32_t, ObjectInfo>&& new_objects_info);
  void UpdateTrailer(RetainPtr<CPDF_Dictionary> new_trailer);

  RetainPtr<CPDF_Dictionary> trailer_;
  std::map<uint32_t, ObjectInfo> objects_info_;
};

#endif  // CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_TABLE_H_
