/** @file */
#include "parsing.h"

/**
 * @brief Attend que l'utilisateur appuie sur entrée pour récupérer la ligne écrite
 * puis la renvoi
 * @return La ligne écrite par l'utilisateur
 */
char *read_line() {
  char c;
  int i = 0;
  
  // buffer overflow attention
  char *buffer = malloc(BUFSIZE * sizeof(char));
  if (buffer == NULL) {
    dprintf(STDERR_FILENO, "Line read buffer allocation error !");
    exit(EXIT_FAILURE);
  }

  while (1) {
    c = getchar();

    if (c == EOF || c == '\n') {
      buffer[i] = '\0';
      return buffer;
    } else {
      buffer[i] = c;
    }
    i++;
    // TODO: realoc quand le buffer est dépassé
  }
}

/**
 * @brief Sépare une ligne par des espaces (pour la ligne "ls -l" ça va renvoyer {"ls",
 * "-l"})
 * @param char *line la ligne à parser
 * @return la liste des arguments de la commande
 */
char **split_line(char *line) {
  char **args = malloc(BUFSIZE * sizeof(char *));
  int i = 0;
  if (args == NULL) {
    dprintf(STDERR_FILENO, "Allocation error");
    exit(EXIT_FAILURE);
  }

  char *token = strtok(line, " ");

  while (token != NULL) {
    args[i] = token;
    i++;
    token = strtok(NULL, " ");
  }
  args[i++] = NULL;

  return args;
}

/**
 * @brief La boucle du shell, elle consiste en trois étapes :
 * - Quand l'utilisateur appui sur entrer pour récupérer son entrée standard
 * - Parser la ligne en fonction de ses espaces
 * - Exécuter la commande demandée
 * @see char* read_line()
 * @see char** split_line(char *line)
 * @see int execute_cmd(char **args)
 */
void shell_loop(disk *disk) {
  char *user = get_env_value("USER");

  if (user == NULL) {
    exit(EXIT_FAILURE);
  }

  char *hostname = get_env_value("HOST");

  char *line;
  char **args;
  int status = 1;

  do {
    // ça aussi c'est pas bien, ça sera à changer une fois le sgf fonctionnel
    dprintf(STDOUT_FILENO, "%s@%s %s> ", user, hostname, get_env_value("PWD"));
    line = read_line();
    args = split_line(line);
    status = execute_cmd(disk, args);

    free(line);
    free(args);
  } while (status);
}

void open_seyshell(disk* disk) {
  env* envs = init_envs();
  shell_loop(disk);
  free(envs);
}

