
#include <map>
#include <string>
#include <vector>
#include "ctx.h"
#include "llm.h"
#include "memory_Context.h"
#include "main.h"

// Exit
//
// Conditions:
// 1. `e`, `exit`, `q`, or `quit` was entered
// 2. Victory has just been reported
memory_Context cli_exit(
  memory_Context c
) {
  if (
    c.recentField == "input" &&
    (
      c.input == "e" ||
      c.input == "exit" ||
      c.input == "q" ||
      c.input == "quit"
    )
  ) {
    c.exit = true;
    c.recentField = "exit";
    return c;
  }
  if (
    c.recentField == "outputVictory"
  ) {
    c.exit = true;
    c.recentField = "exit";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Ask user to go on
//
// Conditions:
// 1. Items have just matched and there are still items left to select
memory_Context cli_goOn(
  memory_Context c
) {
  if (
    c.recentField == "outputMatchedItems" &&
    c.hiddenItems.size() != c.playfieldItems.size()
  ) {
    c.outputGoOn = "Go on:";
    c.recentField = "outputGoOn";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Greet the user
//
// Conditions:
// 1. Just launched
memory_Context cli_greetUser(
  memory_Context c
) {
  if (
    c.recentField == "didLaunch" &&
    c.didLaunch == true
  ) {
    c.outputGreeting = "OGS Memory Command Line Interface";
    c.recentField = "outputGreeting";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Ask user to select second item to have a pair of selected items
//
// Conditions:
// 1. Single item has just been selected
memory_Context cli_promptSecondItemSelection(
  memory_Context c
) {
  if (
    c.recentField == "selectedItems" &&
    c.selectedItems.size() == 1
  ) {
    c.outputPromptSelection = "Select the second item now:";
    c.recentField = "outputPromptSelection";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Report matched items
//
// Conditions:
// 1. Items were hidden (i.e., they matched)
memory_Context cli_reportMatchedItems(
  memory_Context c
) {
  if (
    c.recentField == "hiddenItems"
  ) {
    c.outputMatchedItems = "Items matched!";
    c.recentField = "outputMatchedItems";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Report victory
memory_Context cli_reportVictory(
  memory_Context c
) {
  if (
    c.recentField == "victory"
  ) {
    c.outputVictory = "VICTORY! The game is over now";
    c.recentField = "outputVictory";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Select item
//
// Conditions:
// 1. Id is digit
memory_Context cli_selectItem(
  memory_Context c
) {
  if (
    c.recentField == "input" &&
    llm_isDigit(c.input)
  ) {
    // CLI ids start with 1 while memory module has ids starting with 0
    // Convert CLI id to memory id
    c.selectedId = llm_strToInt(c.input) - 1;
    c.recentField = "selectedId";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Show help (aka commands)
//
// Conditions:
// 1. Just launched
// 1. `h` or `help` was entered
memory_Context cli_showHelp(
  memory_Context c
) {
  if (
    (
      c.recentField == "didLaunch" &&
      c.didLaunch == true
    ) ||
    (
      c.recentField == "input" &&
      c.input == "h"
    ) ||
    (
      c.recentField == "input" &&
      c.input == "help"
    )
  ) {
    c.outputHelp = "Commands:\n\te, exit, q, quit\n\t\tExit\n\th, help\n\t\tList commands\n\t1, 2, 3, ...\n\t\tSelect item\nEnter your choice:";
    c.recentField = "outputHelp";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Report mismatched items
memory_Context cli_reportMismatchedItems(
  memory_Context c
) {
  if (
    c.recentField == "mismatchedItems"
  ) {
    c.outputMismatchedItems = "Wrong! Try again:";
    c.recentField = "outputMismatchedItems";
    return c;
  }
  c.recentField = "none";
  return c;
}

//// Report selection of invalid item ids
////
//// Conditions:
//// 1. Index out of bounds: less than minimum
//// 2. Index out of bounds: greater than maximum
//// 3. Item is already hidden
////@llm_by_value
////def cli_shouldReportInvalidItemSelection(
////  c: cli_Context
////) -> cli_Context:
////  if (
////    c.recentField == "cMemory" and
////    c.cMemory.recentField == "selectedItems" and
////    len(c.cMemory.selectedItems) == 1
////  ):
////    c.outputPromptSelection = "Select the second item now:"
////    c.recentField = "outputPromptSelection"
////    return c
////  //}
////  c.recentField = "none"
////  return c
//////}

