// test_queue_index_compact.cpp - Verify qi_compact_index removes finished/failed tasks
// Validates F4 fix: compact_index actually removes tasks with finished/failed status

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/stat.h>
#include "../queue_index/queue_index.h"

int main() {
    // Create a temporary directory for the queue
    char tmpdir[] = "/tmp/test_compact_XXXXXX";
    if (!mkdtemp(tmpdir)) {
        printf("FAIL: Could not create temp directory\n");
        return 1;
    }
    
    // Open queue index
    qi_index_t* idx = qi_open(tmpdir);
    if (!idx) {
        printf("FAIL: Could not open queue index\n");
        return 1;
    }
    
    // Add tasks with different statuses
    qi_task_t tasks[5];
    memset(tasks, 0, sizeof(tasks));
    
    // Task 0: queued
    strncpy(tasks[0].id, "task_000", sizeof(tasks[0].id));
    strncpy(tasks[0].job_name, "job0", sizeof(tasks[0].job_name));
    strncpy(tasks[0].status, "queued", sizeof(tasks[0].status));
    tasks[0].priority = 100;
    
    // Task 1: finished (should be removed)
    strncpy(tasks[1].id, "task_001", sizeof(tasks[1].id));
    strncpy(tasks[1].job_name, "job1", sizeof(tasks[1].job_name));
    strncpy(tasks[1].status, "finished", sizeof(tasks[1].status));
    tasks[1].priority = 100;
    
    // Task 2: failed (should be removed)
    strncpy(tasks[2].id, "task_002", sizeof(tasks[2].id));
    strncpy(tasks[2].job_name, "job2", sizeof(tasks[2].job_name));
    strncpy(tasks[2].status, "failed", sizeof(tasks[2].status));
    tasks[2].priority = 100;
    
    // Task 3: running
    strncpy(tasks[3].id, "task_003", sizeof(tasks[3].id));
    strncpy(tasks[3].job_name, "job3", sizeof(tasks[3].job_name));
    strncpy(tasks[3].status, "running", sizeof(tasks[3].status));
    tasks[3].priority = 100;
    
    // Task 4: queued
    strncpy(tasks[4].id, "task_004", sizeof(tasks[4].id));
    strncpy(tasks[4].job_name, "job4", sizeof(tasks[4].job_name));
    strncpy(tasks[4].status, "queued", sizeof(tasks[4].status));
    tasks[4].priority = 100;
    
    int added = qi_add_tasks(idx, tasks, 5);
    if (added != 5) {
        printf("FAIL: Could not add tasks (added %d)\n", added);
        qi_close(idx);
        return 1;
    }
    
    printf("Added 5 tasks\n");
    
    // Compact the index (no explicit save needed - happens on close)
    int removed = qi_compact_index(idx);
    if (removed != 2) {
        printf("FAIL: Expected 2 tasks removed, got %d\n", removed);
        qi_close(idx);
        return 1;
    }
    
    // Close and reopen to verify persistence
    qi_close(idx);
    
    idx = qi_open(tmpdir);
    if (!idx) {
        printf("FAIL: Could not reopen queue index\n");
        return 1;
    }
    
    // Get all remaining tasks
    qi_task_t* remaining_tasks = nullptr;
    size_t remaining_count = 0;
    if (qi_get_all_tasks(idx, &remaining_tasks, &remaining_count) != 0) {
        printf("FAIL: Could not get all tasks\n");
        qi_close(idx);
        return 1;
    }
    
    if (remaining_count != 3) {
        printf("FAIL: Expected 3 remaining tasks, got %zu\n", remaining_count);
        qi_free_task_array(remaining_tasks);
        qi_close(idx);
        return 1;
    }
    
    // Verify all remaining tasks are not finished/failed
    for (size_t i = 0; i < remaining_count; i++) {
        if (strcmp(remaining_tasks[i].status, "finished") == 0 ||
            strcmp(remaining_tasks[i].status, "failed") == 0) {
            printf("FAIL: Task %zu has status '%s' after compact\n", i, remaining_tasks[i].status);
            qi_free_task_array(remaining_tasks);
            qi_close(idx);
            return 1;
        }
    }
    
    printf("Remaining %zu tasks have correct statuses\n", remaining_count);
    
    // Cleanup
    qi_free_task_array(remaining_tasks);
    qi_close(idx);
    
    // Remove index file and directory
    char index_path[256];
    snprintf(index_path, sizeof(index_path), "%s/index.bin", tmpdir);
    unlink(index_path);
    rmdir(tmpdir);
    
    printf("PASS: qi_compact_index removes finished/failed tasks (F4 fix verified)\n");
    return 0;
}
