// Copyright 2018 The PDFium Authors
// 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,
    kCompressed = 0x02,
    kObjStream = 0xFF,
    kNull = kObjStream,
  };

  struct ObjectInfo {
    ObjectInfo() = default;

    // If `type` is `ObjectType::kCompressed`, `archive` should be used.
    // If `type` is `ObjectType::kNormal`, `pos` should be used.
    // In other cases, it is unused.
    union {
      FX_FILESIZE pos = 0;
      struct {
        uint32_t obj_num;
        uint32_t obj_index;
      } archive;
    };
    ObjectType type = ObjectType::kFree;
    uint16_t gennum = 0;
  };

  // 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();
  CPDF_CrossRefTable(RetainPtr<CPDF_Dictionary> trailer,
                     uint32_t trailer_object_number);
  ~CPDF_CrossRefTable();

  void AddCompressed(uint32_t obj_num,
                     uint32_t archive_obj_num,
                     uint32_t archive_obj_index);
  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,
                  uint32_t trailer_object_number);
  uint32_t trailer_object_number() const { return trailer_object_number_; }
  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);

  // Objects with object number >= `size` will be removed.
  void SetObjectMapSize(uint32_t size);

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

  RetainPtr<CPDF_Dictionary> trailer_;
  // `trailer_` can be the dictionary part of a XRef stream object. Since it is
  // inline, it has no object number. Store the stream's object number, or 0 if
  // there is none.
  uint32_t trailer_object_number_ = 0;
  std::map<uint32_t, ObjectInfo> objects_info_;
};

#endif  // CORE_FPDFAPI_PARSER_CPDF_CROSS_REF_TABLE_H_
