// pack_resources.cpp
// Tool to pack game resources into a single encrypted file

#include <iostream>
#include <string>
#include <vector>

// Include the ResourcePack class
#include "../../source/core/resources/resource_pack.hpp"

void printUsage(const char* program_name) {
    std::cout << "Usage:\n";
    std::cout << "  " << program_name << " [input_dir] [output_file]\n";
    std::cout << "  " << program_name << " --list <pack_file>\n";
    std::cout << "\n";
    std::cout << "Examples:\n";
    std::cout << "  " << program_name << " data resources.pack\n";
    std::cout << "  " << program_name << " --list resources.pack\n";
    std::cout << "\n";
    std::cout << "Options:\n";
    std::cout << "  --list    List contents of a pack file\n";
}

auto handleDefaultPack() -> int {
    std::string input_dir = "data";
    std::string output_file = "resources.pack";

    std::cout << "Using defaults:\n";
    std::cout << "  Input: " << input_dir << "/\n";
    std::cout << "  Output: " << output_file << "\n\n";

    Resource::Pack pack;
    if (!pack.addDirectory(input_dir)) {
        std::cerr << "Error: Failed to add directory: " << input_dir << '\n';
        return 1;
    }

    // Add config/assets.yaml to pack (required for release builds)
    std::cout << "\nAdding config files...\n";
    if (!pack.addFile("config/assets.yaml", "config/assets.yaml")) {
        std::cerr << "Warning: Failed to add config/assets.yaml (optional)\n";
    }

    if (!pack.savePack(output_file)) {
        std::cerr << "Error: Failed to save pack file: " << output_file << '\n';
        return 1;
    }

    std::cout << "\nSuccess! Pack created: " << output_file << '\n';
    return 0;
}

auto handleListContents(const std::string& pack_file) -> int {
    std::cout << "Loading pack: " << pack_file << "\n\n";

    Resource::Pack pack;
    if (!pack.loadPack(pack_file)) {
        std::cerr << "Error: Failed to load pack file: " << pack_file << '\n';
        return 1;
    }

    std::cout << "\nPack Contents:\n";
    std::cout << "==============\n";

    auto resources = pack.getResourceList();
    size_t total_size = 0;

    for (const auto& resource : resources) {
        auto data = pack.getResource(resource);
        total_size += data.size();
        std::cout << "  " << resource << " (" << data.size() << " bytes)\n";
    }

    std::cout << "\nTotal Resources: " << resources.size() << '\n';
    std::cout << "Total Size: " << total_size << " bytes\n";
    return 0;
}

auto handlePackDirectory(const std::string& input_dir, const std::string& output_file) -> int {
    std::cout << "Input: " << input_dir << "/\n";
    std::cout << "Output: " << output_file << "\n\n";

    Resource::Pack pack;
    if (!pack.addDirectory(input_dir)) {
        std::cerr << "Error: Failed to add directory: " << input_dir << '\n';
        return 1;
    }

    // Add config/assets.yaml to pack (required for release builds)
    std::cout << "\nAdding config files...\n";
    if (!pack.addFile("config/assets.yaml", "config/assets.yaml")) {
        std::cerr << "Warning: Failed to add config/assets.yaml (optional)\n";
    }

    if (!pack.savePack(output_file)) {
        std::cerr << "Error: Failed to save pack file: " << output_file << '\n';
        return 1;
    }

    std::cout << "\nSuccess! Pack created: " << output_file << '\n';
    return 0;
}

auto main(int argc, char* argv[]) -> int {
    std::cout << "Projecte 2026 - Resource Packer\n";
    std::cout << "======================================\n\n";

    // Default behavior: pack data/ into resources.pack
    if (argc == 1) {
        return handleDefaultPack();
    }

    // Help command
    if (argc == 2) {
        std::string arg = argv[1];
        if (arg == "--help" || arg == "-h") {
            printUsage(argv[0]);
            return 0;
        }
    }

    // List contents or pack directory
    if (argc == 3) {
        std::string arg1 = argv[1];
        std::string arg2 = argv[2];

        if (arg1 == "--list" || arg1 == "-l") {
            return handleListContents(arg2);
        }

        return handlePackDirectory(arg1, arg2);
    }

    // Invalid arguments
    std::cerr << "Error: Invalid arguments\n\n";
    printUsage(argv[0]);
    return 1;
}
