// 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 "utils.h"
#include <glob.h>
#include <readline/history.h>
#include <readline/readline.h>
#include <stdbool.h>
#include <string.h>
#define HISTORY_FILE "~/.r_history"

bool line_initialized = false;

char *get_history_file() {
  static char result[4096];
  result[0] = 0;

  char *expanded = expand_home_directory(HISTORY_FILE);
  strcpy(result, expanded);
  free(expanded);
  return result;
}

char *line_command_generator(const char *text, int state) {
  static int list_index, len = 0;
  const char *commands[] = {"help",     "exit",      "list",     "review",
                            "refactor", "obfuscate", "!verbose", "!dump",
                            "!model",   "!debug",    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(get_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(get_history_file());
}
