#include "{include}"

/* HELPER CONSTANTS */

static const int _SH_INIT_BUFFER = 23;

/* HELPER FUNCTIONS SIGNATURES */

void shu_print_command_help(char *command_name, char *command_description, sh_param_details *details, int details_size);

/* EXPORTED VARIABLES */

char *sh_last_command;
char *sh_prompt_symbol = "{prompt_symbol}";
bool sh_use_advanced_terminal = true;

/* EXPORTED FUNCTIONS */

{handle_command_functions}

{help_handler_functions}

{help_function}

{parse_command_function}

void sh_loop() {{
    SH_STATE state = SH_CONTINUE;

    int n_words;
    char *command, **words;
	
	int history_size = 8, history_index = 0, temp;
	char** history = malloc(history_size * sizeof(char*));

    sh_last_command = strdup("");

    while (state != SH_EXIT) {{
        printf("%s", sh_prompt_symbol);
        fflush(stdout);

        command = sh_use_advanced_terminal 
            ? txt_readline_special(history, history_index)
            : txt_readline();

        free(sh_last_command);
        sh_last_command = strdup(command);

		if (history_index == history_size) {{
			history_size *= 2;
			history = realloc(history, history_size * sizeof(char*));
		}}

		history[history_index] = strdup(command);
		history[history_index][strlen(command) - 1] = '\0';
		history_index++;

        words = txt_splitline(command, &n_words);
        state = sh_parse_command(words, n_words);

        free(command);
        txt_free_string_array(words, n_words);
    }}
}}

/* HELPER FUNCTIONS DEFINITIONS */

void shu_print_command_help(char *command_name, char *command_description, sh_param_details *details, int details_size) {{
  printf("%-15s", command_name);
  if (command_description != NULL) {{
    printf("%s\n", command_description);
  }} 
  else {{
    printf("\n");
  }}
  int i;
  for (i = 0; i < details_size; i++) {{
    printf("--%-13s", details[i].name);
    
    printf("-%-9s", details[i].alias);
    printf("%-15s", details[i].type);
    if(details[i].default_value != NULL) {{
      printf("default: %-11s", details[i].default_value);
    }} 
    else {{
      printf("%-20s", "required");
    }}
    if(details[i].description != NULL) {{
      printf("%-80s\n", details[i].description);
    }} 
    else {{
      printf("%-80s\n", "no description");
    }}
  }}
  printf("\n");
}}