#include "Agent.h"
#include "printError.h"
#include <stdio.h>

// TODO: Move this include to ControlModule
#include "instruction_set_architecture.h"

#define PRINT_READING

void Agent::init_agent() {
  sensorHandlerOfAgent = NULL;
  slaveAgentHandlerOfAgent = NULL;
  masterAgentHandlerOfAgent = NULL;
}

Agent::Agent() {
  set_name(NO_NAME);
  init_agent();
}

Agent::Agent(const char *name) {
  set_name(name);
  init_agent();
}

bool Agent::set_sensorHandlerOfAgent() {
  sensorHandlerOfAgent = new SensorHandlerOfAgent();

  if (sensorHandlerOfAgent == NULL) {
    printError("Couldn't create Sensor Handler!");
    return false;
  }
  return true;
}

bool Agent::del_sensorHandlerOfAgent() {
  if (sensorHandlerOfAgent != NULL) {
    // TODO: Unmount/delete all sensorSlots with everything inside (history
    // module, confidence module, ...)
    delete sensorHandlerOfAgent;
    return true;
  }
  return false;
}

SensorHandlerOfAgent *Agent::get_sensorHandlerOfAgent() {
  if (sensorHandlerOfAgent == NULL) {
    set_sensorHandlerOfAgent();
  }
  return sensorHandlerOfAgent;
}

bool Agent::set_slaveAgentHandlerOfAgent() {
  slaveAgentHandlerOfAgent = new SlaveAgentHandlerOfAgent();

  if (slaveAgentHandlerOfAgent == NULL) {
    printError("Couldn't create Slave Agent Handler!");
    return false;
  }
  return true;
}

bool Agent::del_slaveAgentHandlerOfAgent() {
  if (slaveAgentHandlerOfAgent != NULL) {
    // TODO: Unmount/delete all SlaveAgentSlots with everything inside (history
    // module, confidence module, ...)
    delete slaveAgentHandlerOfAgent;
    return true;
  }
  return false;
}

SlaveAgentHandlerOfAgent *Agent::get_slaveAgentHandlerOfAgent() {
  if (slaveAgentHandlerOfAgent == NULL) {
    set_slaveAgentHandlerOfAgent();
  }
  return slaveAgentHandlerOfAgent;
}

bool Agent::set_masterAgentHandlerOfAgent() {
  masterAgentHandlerOfAgent = new MasterAgentHandlerOfAgent();

  if (masterAgentHandlerOfAgent == NULL) {
    printError("Couldn't create Master Agent Handler!");
    return false;
  }
  return true;
}

bool Agent::del_masterAgentHandlerOfAgent() {
  if (masterAgentHandlerOfAgent != NULL) {
    // TODO: Unmount/delete (all) MasterAgentSlot(s) with everything inside
    delete masterAgentHandlerOfAgent;
    return true;
  }
  return false;
}

MasterAgentHandlerOfAgent *Agent::get_masterAgentHandlerOfAgent() {
  if (masterAgentHandlerOfAgent == NULL) {
    set_masterAgentHandlerOfAgent();
  }
  return masterAgentHandlerOfAgent;
}

void Agent::trigger() {

  // TODO: make control_module to set the method of operating for each agent
  // individual

  // Job: Read all sensory data
  if (sensorHandlerOfAgent != NULL) {
    printf("%s->sensorHandler: ", name);
    sensorHandlerOfAgent->read_allSensorValues();
  }

  // Job: Read all slave agent data
  if (slaveAgentHandlerOfAgent != NULL) {
    printf("%s->slaveAgentHandler: ", name);
    slaveAgentHandlerOfAgent->read_allSlaveAgentValues();
  }

  // Job: Just pass the Sensory Data (without abstraction) to master
  if (masterAgentHandlerOfAgent != NULL) {
    if (sensorHandlerOfAgent != NULL) {
      vector<SensorSlotOfAgent *> *vSensoryData =
          sensorHandlerOfAgent->get_vMountedSensors();
      for (auto &sensorSlot : *vSensoryData) {
        // TODO: also for int
        float sensorValue;
        if (sensorSlot->get_sensorValue(&sensorValue)) {
          masterAgentHandlerOfAgent->pass_msgToSendBuffer(ISA_SensoryData);
          masterAgentHandlerOfAgent->pass_msgToSendBuffer(sensorValue);
        }
      }
    }
    masterAgentHandlerOfAgent->send_msgs();
  }
}

