#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "action.h"
#include "effect.h"
#include "predicate.h"
#include "game.h"
#include "parse.h"
#include "util.h"

void load_action(Game *g, char *line) {
  Action *action = &g->actions->actions[g->actions->count];
  action->words_count = 0;
  action->predicates_count = 0;
  action->effects_count = 0;

  char *line_token_guy;
  char *line_token = strtok_r(line, "|", &line_token_guy);

  char command_buffer[200];
  strcpy(command_buffer, line_token);

  char *command_token_guy;
  char *command_word = strtok_r(command_buffer, " ", &command_token_guy);
  while (command_word != NULL) {
    Word *word = find_word(g->words, command_word);
    action->words[action->words_count++] = word;
    command_word = strtok_r(NULL, " ", &command_token_guy);
  }

  line_token = strtok_r(NULL, "|", &line_token_guy);
  strcpy(command_buffer, line_token);
  command_word = strtok_r(command_buffer, " &", &command_token_guy);
  while (command_word != NULL) {
    Predicate *p = create_predicate(g, command_word);
    action->predicates[action->predicates_count++] = p;
    command_word = strtok_r(NULL, " &", &command_token_guy);
  }

  line_token = strtok_r(NULL, "|", &line_token_guy);
  action->priority = atoi(line_token);

  line_token = strtok_r(NULL, "|", &line_token_guy);
  action->description = malloc(strlen(line_token) + 1);
  strcpy(action->description, line_token);

  line_token = strtok_r(NULL, "|", &line_token_guy);
  if (line_token == NULL) {
  } else {
    strcpy(command_buffer, line_token);
    command_word = strtok_r(command_buffer, " &", &command_token_guy);
    while (command_word != NULL) {
      Effect *e = create_effect(g, command_word);
      action->effects[action->effects_count++] = e;
      command_word = strtok_r(NULL, " &", &command_token_guy);
    }
  }

  g->actions->count++;
}

#include "data/actions.c"
void game_load_actions(Game *g) {
  g->actions = malloc(sizeof(Actions));
  g->actions->count = 0;
  parse_multiline_string(g, data_actions_txt, &load_action);
  printf("loaded actions\n");
}

Action *find_action(Game *g, const char *command) {
  Command *c = parse(g, command);
  int priority = -1;
  Action *a = NULL;
  bool failed_predicate;
  for (int i = 0; i < g->actions->count; i++) {
    Action *ca = &g->actions->actions[i];
    if (ca->priority < priority) continue;
    for (int j = 0; j < ca->words_count; j++) {
      if (c->words[j] == NULL) break;
      if (c->words[j] != ca->words[j]) break;
      failed_predicate = false;
      for (int k = 0; k < ca->predicates_count; k++) {
	if (!predicate_fulfilled(g, ca->predicates[k])) failed_predicate = true;
      }
      if (failed_predicate) break;
      if (j == ca->words_count - 1) {
	priority = ca->priority;
	a = ca;
      }
    }
  }
  return a;
}