#include "ai.hpp"
#include "ai_debug.hpp"

namespace ai {

  /*
   * Yeah this is weird but it's only to debug things like
   * the preconditions which are weirdly done.
   */
  void dump_only(State state, bool matching, bool show_as) {
    AIProfile* profile = ai::profile();
    for(auto& [name, name_id] : *profile) {
      if(state.test(name_id) == matching) {
        fmt::println("\t{}={}", name, show_as);
      }
    }
  }

  void dump_state(State state) {
    AIProfile* profile = ai::profile();
    for(auto& [name, name_id] : *profile) {
      fmt::println("\t{}={}", name,
          state.test(name_id));
    }
  }

  void dump_action(Action& action) {
    fmt::println(" --ACTION: {}, cost={}", action.name, action.cost);

    fmt::println("   PRECONDS:");
    dump_only(action.$positive_preconds, true, true);
    dump_only(action.$negative_preconds, true, false);

    fmt::println("   EFFECTS:");
    dump_only(action.$positive_effects, true, true);
    dump_only(action.$negative_effects, true, false);
  }

  State dump_script(std::string msg, State start, Script& script) {
    fmt::println("--SCRIPT DUMP: {}", msg);
    fmt::println("# STATE BEFORE:");
    dump_state(start);
    fmt::print("% ACTIONS PLANNED:");
    for(auto& action : script) {
      fmt::print("{} ", action.name);
    }
    fmt::print("\n");

    for(auto& action : script) {
      dump_action(action);

      start = action.apply_effect(start);
      fmt::println(" ## STATE AFTER:");
      dump_state(start);
    }

    return start;
  }

  void EntityAI::dump() {
    dump_script(script, start, plan.script);
  }

}
