#pragma once
#include <whiteout/common_types.h>
#include <whiteout/interfaces.h>
#include <array>
#include <memory>
#include <span>
#include <string>
#include <vector>
#include "flat_hash_map.h"
namespace whiteout::storages::casc {
class CdnFetcher; class KeyRing;
struct EncodingEntry {
std::array<u8, 16> cKey{};
std::array<u8, 16> eKey{}; u64 fileSize = 0; std::string eSpec; };
class EncodingTable {
public:
EncodingTable();
~EncodingTable();
EncodingTable(EncodingTable&&) noexcept;
EncodingTable& operator=(EncodingTable&&) noexcept;
EncodingTable(const EncodingTable&) = delete;
EncodingTable& operator=(const EncodingTable&) = delete;
static EncodingTable parse(std::span<const u8> data, interfaces::WorkerPool* pool = nullptr);
static EncodingTable openLazy(std::span<const u8> data, interfaces::WorkerPool* pool = nullptr);
static EncodingTable openLazyOnline(CdnFetcher* fetcher, const std::string& archiveKeyHex,
u64 archiveOffset, u32 encodedSize,
const KeyRing* keys = nullptr,
interfaces::WorkerPool* pool = nullptr);
class LazyEncodingBlob;
void ensureFullyParsed() const;
bool isValid() const;
const EncodingEntry* findByCKey(std::span<const u8, 16> cKey, size_t matchBytes = 0) const;
const EncodingEntry* findByEKey(std::span<const u8, 16> eKey, size_t matchBytes = 0) const;
void insert(const EncodingEntry& entry);
std::vector<u8> serialize() const;
size_t entryCount() const;
const std::vector<EncodingEntry>& entries() const;
private:
mutable std::vector<EncodingEntry> m_entries;
mutable FlatHashMap<size_t> m_cKeyIndex;
mutable FlatHashMap<size_t> m_eKeyIndex;
struct LazyState;
mutable std::unique_ptr<LazyState> m_lazy;
void parseCKeyPage(u32 pageIdx) const;
static bool initLazyFromBlob(LazyState& state, std::unique_ptr<LazyEncodingBlob> blob);
};
}