// resource_pack.hpp
// Resource pack file format and management for JailDoctor's Dilemma
// Based on Coffee Crisis Arcade Edition resource pack system

#ifndef RESOURCE_PACK_HPP
#define RESOURCE_PACK_HPP

#include <array>
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>

namespace Resource {

// Entry metadata for each resource in the pack
struct ResourceEntry {
        std::string filename;  // Relative path within pack
        uint64_t offset;       // Byte offset in data block
        uint64_t size;         // Size in bytes
        uint32_t checksum;     // CRC32 checksum for verification
};

// Resource pack file format
// Header: "JDDI" (4 bytes) + Version (4 bytes)
// Metadata: Count + array of ResourceEntry
// Data: Encrypted data block
class Pack {
    public:
        Pack() = default;
        ~Pack() = default;

        // Disable copy/move
        Pack(const Pack&) = delete;
        auto operator=(const Pack&) -> Pack& = delete;
        Pack(Pack&&) = delete;
        auto operator=(Pack&&) -> Pack& = delete;

        // Add a single file to the pack
        auto addFile(const std::string& filepath, const std::string& pack_name) -> bool;

        // Add all files from a directory recursively
        auto addDirectory(const std::string& dir_path, const std::string& base_path = "")
            -> bool;

        // Save the pack to a file
        auto savePack(const std::string& pack_file) -> bool;

        // Load a pack from a file
        auto loadPack(const std::string& pack_file) -> bool;

        // Get a resource by name
        auto getResource(const std::string& filename) -> std::vector<uint8_t>;

        // Check if a resource exists
        auto hasResource(const std::string& filename) const -> bool;

        // Get list of all resources
        auto getResourceList() const -> std::vector<std::string>;

        // Check if pack is loaded
        auto isLoaded() const -> bool { return loaded_; }

        // Get pack statistics
        auto getResourceCount() const -> size_t { return resources_.size(); }
        auto getDataSize() const -> size_t { return data_.size(); }

        // Calculate overall pack checksum (for validation)
        auto calculatePackChecksum() const -> uint32_t;

    private:
        static constexpr std::array<char, 4> MAGIC_HEADER = {'J', 'D', 'D', 'I'};
        static constexpr uint32_t VERSION = 1;
        static constexpr const char* DEFAULT_ENCRYPT_KEY = "JDDI_RESOURCES_2024";

        // Calculate CRC32 checksum
        static auto calculateChecksum(const std::vector<uint8_t>& data) -> uint32_t;

        // XOR encryption/decryption
        static void encryptData(std::vector<uint8_t>& data, const std::string& key);
        static void decryptData(std::vector<uint8_t>& data, const std::string& key);

        // Read file from disk
        static auto readFile(const std::string& filepath) -> std::vector<uint8_t>;

        // Member data
        std::unordered_map<std::string, ResourceEntry> resources_;
        std::vector<uint8_t> data_;  // Encrypted data block
        bool loaded_{false};
};

}  // namespace Resource

#endif  // RESOURCE_PACK_HPP
