#include <iostream>
#include <string>
#include <vector>
#include "any.h"
#include "ctx_test2.h"
#include "llm.h"
#include "main.h"
#include "memory_Context.h"

int main() {
  std::cout
    << test_ctx_Controller_executeFunctions_registerFunction_set()
    << std::endl
    << test_ctx_Controller_processQueue()
    << std::endl
    << test_ctx_Controller_registerFieldCallback_match()
    << std::endl
    << test_ctx_Controller_registerFieldCallback_mismatch()
    << std::endl
    << test_memory_Context_field()
    << std::endl
    << test_memory_Context_setField()
    << std::endl
    << llm_test_isDigit_digit()
    << std::endl
    << llm_test_isDigit_notDigit()
    << std::endl
    << llm_test_strToInt()
    << std::endl
    ;

  std::cout
    << memory_test_detectMismatchedItems()
    << std::endl
    << memory_test_detectMismatchedItems_itemTwice()
    << std::endl
    << memory_test_detectVictory()
    << std::endl
    << memory_test_generateConstPlayfield()
    << std::endl
    << memory_test_hideMatchingItems()
    << std::endl
    << memory_test_selectItem_1x()
    << std::endl
    << memory_test_selectItem_2x()
    << std::endl
    << memory_test_selectItem_3x()
    << std::endl
    ;

  std::cout
    << cli_test_exit_e()
    << std::endl
    << cli_test_exit_exit()
    << std::endl
    << cli_test_exit_victory()
    << std::endl
    << cli_test_exit_q()
    << std::endl
    << cli_test_exit_quit()
    << std::endl
    << cli_test_goOn()
    << std::endl
    << cli_test_greetUser()
    << std::endl
    << cli_test_showHelp_h()
    << std::endl
    << cli_test_showHelp_help()
    << std::endl
    << cli_test_selectItem()
    << std::endl
    << cli_test_promptSecondItemSelection()
    << std::endl
    << cli_test_reportMatchedItems()
    << std::endl
    << cli_test_reportMismatchedItems()
    << std::endl
    << cli_test_reportVictory()
    << std::endl
    ;

  ctx_Controller<memory_Context> ctrl(memory_createContext());
  ctrl.registerFunctions({
    cli_exit,
    cli_goOn,
    cli_greetUser,
    cli_promptSecondItemSelection,
    cli_reportMatchedItems,
    cli_reportMismatchedItems,
    cli_reportVictory,
    cli_selectItem,
    cli_showHelp,
    memory_detectMismatchedItems,
    memory_detectVictory,
    memory_generateConstPlayfield,
    memory_hideMatchingItems,
    memory_selectItem,
  });


  auto printOutput = [](memory_Context c) {
    if (llm_startsWith(c.recentField, "output")) {
      std::cout
        << libany::any_cast<std::string>(c.field(c.recentField))
        << std::endl;
    }
  };
  ctrl.registerCallback(printOutput);
  ctrl.registerFieldCallback("exit", [](memory_Context c) { exit(0); });

  ctrl.set("didLaunch", true);
  ctrl.set("playfieldSize", 2);

  while (true) {
    std::string ln;
    getline(std::cin, ln);
    ctrl.set("input", ln);
  }
}
