#ifndef VKZ_FORMAT_H
#define VKZ_FORMAT_H

#include "utils.h"

// ── Magic number & version ─────────────────────────────────────────
#define VKZ_MAGIC 0x5A4B5600 // "VKZ\0" in little-endian
#define VKZ_VERSION 1

// ── Flags ──────────────────────────────────────────────────────────
#define VKZ_FLAG_DIRECTORY                                                     \
  0x01 // Archive was created from a directory (tar inside)

// ── Archive header ─────────────────────────────────────────────────
#pragma pack(push, 1)

typedef struct {
  uint32_t magic;         // VKZ_MAGIC
  uint32_t version;       // VKZ_VERSION
  uint64_t original_size; // Total uncompressed size
  uint32_t block_size;    // Size of each uncompressed block
  uint32_t block_count;   // Number of blocks
  uint32_t flags;         // Compression flags (future use)
  uint32_t checksum;      // CRC32 of original data
} VkzHeader;

typedef struct {
  uint64_t compressed_offset; // Offset of compressed data in file
  uint32_t compressed_size;   // Size of compressed block
  uint32_t original_size;     // Original block size (last may be smaller)
  uint32_t checksum;          // CRC32 of this block
} VkzBlockEntry;

#pragma pack(pop)

// ── Archive structure ──────────────────────────────────────────────
typedef struct {
  VkzHeader header;
  VkzBlockEntry *blocks; // Array of block entries
  char original_filename[VKZ_MAX_FILENAME];
} VkzArchive;

// ── Functions ──────────────────────────────────────────────────────

// Create a new archive structure
VkzArchive *vkz_create(uint64_t original_size, uint32_t block_size,
                       const char *original_filename);

// Write archive to file
int vkz_write(const VkzArchive *archive, const uint8_t **compressed_blocks,
              const char *output_path);

// Read archive from file (header + block table only)
VkzArchive *vkz_read(const char *archive_path);

// Read a specific compressed block from archive
uint8_t *vkz_read_block(const char *archive_path, const VkzArchive *archive,
                        uint32_t block_index, uint32_t *out_size);

// Free archive structure
void vkz_free(VkzArchive *archive);

// CRC32 checksum
uint32_t vkz_crc32(const uint8_t *data, size_t length);

// Print archive info
void vkz_print_info(const VkzArchive *archive);

#endif // VKZ_FORMAT_H
