// Written by retoor@molodetz.nl

// This source code provides command-line input functionalities with autocomplete and history features using the readline library. It allows users to complete commands and manage input history.

// External includes: 
// - <readline/readline.h>
// - <readline/history.h>
// - <glob.h>

// MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction.

#include <readline/readline.h>
#include <readline/history.h>
#include <string.h>
#include <stdbool.h>
#include <glob.h>

#define HISTORY_FILE ".r_history"

bool line_initialized = false;

char* line_command_generator(const char* text, int state) {
    static int list_index, len = 0;
    const char* commands[] = {"help", "exit", "list", "review", "refactor", "obfuscate", NULL};

    if (!state) {
        list_index = 0;
        len = strlen(text);
    }

    while (commands[list_index]) {
        const char* command = commands[list_index++];
        if (strncmp(command, text, len) == 0) {
            return strdup(command);
        }
    }

    return NULL;
}

char* line_file_generator(const char* text, int state) {
    static int list_index;
    glob_t glob_result;
    char pattern[1024];

    if (!state) {
        list_index = 0;
        snprintf(pattern, sizeof(pattern), "%s*", text); // Create a pattern for glob
        glob(pattern, GLOB_NOSORT, NULL, &glob_result);
    }

    if (list_index < glob_result.gl_pathc) {
        return strdup(glob_result.gl_pathv[list_index++]);
    }

    globfree(&glob_result);
    return NULL;
}

char** line_command_completion(const char* text, int start, int end) {
    rl_attempted_completion_over = 1;

    // Check if the input is a file path
    if (start > 0 && text[0] != ' ') {
        return rl_completion_matches(text, line_file_generator);
    }

    return rl_completion_matches(text, line_command_generator);
}

void line_init() {
    if (!line_initialized) {
        rl_attempted_completion_function = line_command_completion;
        line_initialized = true;
        read_history(HISTORY_FILE);
    }
}

char* line_read(char* prefix) {
    char* data = readline(prefix);
    if (!(data && *data)) {
        free(data);
        return NULL;
    }
    return data;
}

void line_add_history(char* data) {
    add_history(data);
    write_history(HISTORY_FILE);
}