/*
 Program testujący API aplikacji dla wypożyczalni DVD
*/

#include <stdlib.h>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <string.h>
#include "dvd.h"

int show_result(char *, int);
int execute_command(char *);
void initialize_readline(void);

int main()
{
  char *command;

  printf("DVD Store Application\n");

  dvd_open_db();

    /* Nie otwierać bazy danych, będą testy */
  /* printf("Warning, database is not open\n"); */

  /* Inicjacja interfejsu wiersza poleceń */
  initialize_readline();

  /* Główna pętla, odczyt i uruchomienie poleceń */
  while(1) {
    command = readline("> ");
    if(command == NULL)
      break;
    if(*command != '\0') {
      add_history(command);
      show_result("!", execute_command(command));
    }
    free(command);
  }
  exit(EXIT_SUCCESS);
}

void initialize_readline()
{
  /* Wyłączenie uzupełniania nazw plików klawiszem TAB */
  rl_bind_key('\t', rl_insert);
}

int show_result(char *msg, int err)
{
  char *err_msg;

  (void) dvd_err_text(err, &err_msg);
  printf("%s: %s\n", msg, err_msg);
  return err == DVD_SUCCESS;
}

int help_function(int argc, char *argv[]);
int quit_function(int argc, char *argv[]);
int member_function(int argc, char *argv[]);
int title_function(int argc, char *argv[]);
int disk_function(int argc, char *argv[]);

typedef int Func(int, char **);

struct {
  char *name;
  Func *func;
  char *help;
} functions[] = {
  {"help", help_function, "summary of functions"},
  {"quit", quit_function, "quit the application"},
  {"title", title_function, "create, set, get, search titles"},
  {"member", member_function, "create, set, get, search members"},
  {"disk", disk_function, "create, set, get, search disks"},
  {NULL, NULL, NULL}
};

int help_function(int argc, char *argv[])
{
  int f;

  printf("These functions are available:\n");
  for(f = 0; functions[f].name; f++)
    printf("%s \t%s\n", functions[f].name, functions[f].help);
  printf("To get more help try <command> help\n");

  return DVD_SUCCESS;
}

int quit_function(int argc, char *argv[])
{
  dvd_close_db();
  exit(EXIT_SUCCESS);
}

void print_title(dvd_title *dvd)
{
  printf("DVD Title #%d: %s\n", dvd -> title_id, dvd -> title_text);
  printf("Directed by %s (%s), Rated: %s, %s\n", dvd -> director,
    dvd -> release_date, dvd -> classification, dvd -> genre);
  printf("Starring: %s %s\n", dvd -> actor1, dvd -> actor2);
  printf("ASIN %s, Price %s\n", dvd -> asin, dvd -> rental_cost);
}

int title_function(int argc, char *argv[])
{
  if(argc < 2)
    return DVD_ERR_NOT_FOUND;

  if(argc == 3 && strcmp(argv[1], "get") == 0) {
    dvd_title dvd;
    if(show_result("title get", dvd_title_get(atoi(argv[2]), &dvd)))
      print_title(&dvd);
  }

  if(argc == 4 && strcmp(argv[1], "search") == 0) {
    int count;
    int *results;
    int i;
    
    show_result("title search",
      dvd_title_search(argv[2], argv[3], &results, &count));
    for(i = 0; i < count; i++)
      printf("[%d]",results[i]);
    printf("\n");
  }
  else {
    return DVD_ERR_NOT_FOUND;
  }
  return DVD_SUCCESS;
}

int member_function(int argc, char *argv[])
{
  return DVD_SUCCESS;
}


int disk_function(int argc, char *argv[])
{
  return DVD_SUCCESS;
}

int execute_command(char *command)
{
  /* Podział polecenia na elementy oddzielone przecinkami*/
  char *string = command;
  char *token;
  char *items[20];
  int item = 0, i;
  char *cmd1, *cmd2;
  int f;
  /* Polecenia zawierają albo pojedyncze słowo albo dwa słowa,
     za którymi następuje lista argumentów oddzielonych przecinkami */

  cmd1 = strsep(&string, " ");
  items[item++] = cmd1;

  cmd2 = strsep(&string, " ");
  if(cmd2 == NULL)
    items[item] = NULL;
  else
    items[item++] = cmd2;

  if(cmd2) {
   /* Podział argumentów */
    while(1) {
      token = strsep(&string,",");
      if(token == NULL) {
   /* Ostatni element */
   /* items[item++] = string; */
   break;
      }
      else
   items[item++] = token;
    };
    
    items[item] = NULL;
  }

  for(i = 0; i < item; i++)
    printf("[%s]", items[i]);
  printf("\n");

  /* Teraz wywołanie odpowiedniej funkcji dla cmd1 */
  for(f = 0; functions[f].name != NULL; f++) {
    if(strcmp(cmd1, functions[f].name) == 0) {
      (*functions[f].func)(item, items);
      break;
    }
  }
  if(functions[f].name == NULL)
    return DVD_ERR_NOT_FOUND;

  return DVD_SUCCESS;
}

