#include <cassert>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include "queue_index/storage/index_storage.h"

// Simple recursive rmdir (replacement for std::filesystem::remove_all)
static void rmdir_recursive(const char* path) {
    // Simplified - just remove the directory contents and itself
    char cmd[4096];
    snprintf(cmd, sizeof(cmd), "rm -rf %s", path);
    system(cmd);
}

int main() {
    const char* tmp_dir = "/tmp/queue_index_test";
    
    // Clean up and create temp directory
    rmdir_recursive(tmp_dir);
    mkdir(tmp_dir, 0755);
    
    // Test 1: Create and open storage
    {
        IndexStorage storage;
        assert(storage_init(&storage, tmp_dir) && "Failed to init storage");
        assert(storage_open(&storage) && "Failed to open storage");
        printf("Storage open\n");
        storage_close(&storage);
        storage_cleanup(&storage);
    }
    
    // Test 2: Write and read entries
    {
        IndexStorage storage;
        assert(storage_init(&storage, tmp_dir) && "Failed to init storage");
        assert(storage_open(&storage) && "Failed to open storage");
        
        DiskEntry entries[2];
        memset(entries, 0, sizeof(entries));
        memcpy(entries[0].id, "task-001", 8);
        memcpy(entries[0].job_name, "test-job", 8);
        entries[0].priority = 100;
        entries[0].created_at = 1234567890;
        
        memcpy(entries[1].id, "task-002", 8);
        memcpy(entries[1].job_name, "test-job-2", 10);
        entries[1].priority = 50;
        entries[1].created_at = 1234567891;
        
        assert(storage_write_entries(&storage, entries, 2) && "Failed to write entries");
        printf("Write entries\n");
        
        // Close and reopen to ensure we read the new file
        storage_close(&storage);
        assert(storage_open(&storage) && "Failed to reopen storage");
        
        DiskEntry read_entries[2];
        size_t count = 0;
        assert(storage_read_entries(&storage, read_entries, 2, &count) && "Failed to read entries");
        assert(count == 2 && "Wrong entry count");
        assert(memcmp(read_entries[0].id, "task-001", 8) == 0 && "Entry 0 ID mismatch");
        assert(read_entries[0].priority == 100 && "Entry 0 priority mismatch");
        printf("Read entries\n");
        
        // Suppress unused warnings in release builds where assert is no-op
        (void)read_entries;
        (void)count;
        
        storage_close(&storage);
        storage_cleanup(&storage);
    }
    
    // Test 3: Mmap read
    {
        IndexStorage storage;
        assert(storage_init(&storage, tmp_dir) && "Failed to init storage");
        assert(storage_open(&storage) && "Failed to open storage");
        assert(storage_mmap_for_read(&storage) && "Failed to mmap");
        
        size_t count = storage_mmap_entry_count(&storage);
        assert(count == 2 && "Mmap entry count mismatch");
        
        const DiskEntry* entries = storage_mmap_entries(&storage);
        assert(entries != nullptr && "Mmap entries null");
        assert(memcmp(entries[0].id, "task-001", 8) == 0 && "Mmap entry 0 ID mismatch");
        printf("Mmap read\n");
        
        // Suppress unused warnings in release builds where assert is no-op
        (void)count;
        (void)entries;
        
        storage_munmap(&storage);
        storage_close(&storage);
        storage_cleanup(&storage);
    }
    
    // Cleanup
    rmdir_recursive(tmp_dir);
    
    printf("\nAll storage tests passed!\n");
    return 0;
}
