#include "PcduHandlerDummy.h"

#include <fsfw/ipc/QueueFactory.h>
#include <mission/power/gsDefs.h>

#include "mission/power/defs.h"

PcduHandlerDummy::PcduHandlerDummy(object_id_t objectId)
    : SystemObject(objectId), manager(this, nullptr), dummySwitcher(objectId, 18, 18, false) {
  switcherLock = MutexFactory::instance()->createMutex();
  queue = QueueFactory::instance()->createMessageQueue(20);
}

PcduHandlerDummy::~PcduHandlerDummy() {}

ReturnValue_t PcduHandlerDummy::initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
                                                        LocalDataPoolManager& poolManager) {
  return returnvalue::OK;
}

ReturnValue_t PcduHandlerDummy::sendSwitchCommand(power::Switch_t switchNr, ReturnValue_t onOff) {
  if (onOff == SWITCH_ON) {
    triggerEvent(power::SWITCH_CMD_SENT, true, switchNr);
  } else {
    triggerEvent(power::SWITCH_CMD_SENT, false, switchNr);
  }
  {
    MutexGuard mg(switcherLock);
    // To simulate a real PCDU, remember the switch change to trigger a SWITCH_HAS_CHANGED event
    // at a later stage.
    switchChangeArray[switchNr] = true;
  }
  return dummySwitcher.sendSwitchCommand(switchNr, onOff);
}

ReturnValue_t PcduHandlerDummy::sendFuseOnCommand(uint8_t fuseNr) {
  return dummySwitcher.sendFuseOnCommand(fuseNr);
}

ReturnValue_t PcduHandlerDummy::getSwitchState(power::Switch_t switchNr) const {
  return dummySwitcher.getSwitchState(switchNr);
}

ReturnValue_t PcduHandlerDummy::getFuseState(uint8_t fuseNr) const {
  return dummySwitcher.getFuseState(fuseNr);
}

uint32_t PcduHandlerDummy::getSwitchDelayMs(void) const { return dummySwitcher.getSwitchDelayMs(); }

ReturnValue_t PcduHandlerDummy::performOperation(uint8_t opCode) {
  // TODO: Handle HK messages in queue.
  SwitcherBoolArray switcherChangeCopy{};
  {
    MutexGuard mg(switcherLock);
    std::memcpy(switcherChangeCopy.data(), switchChangeArray.data(), switchChangeArray.size());
  }
  for (uint8_t idx = 0; idx < switcherChangeCopy.size(); idx++) {
    if (switcherChangeCopy[idx]) {
      if (dummySwitcher.getSwitchState(idx) == PowerSwitchIF::SWITCH_ON) {
        triggerEvent(power::SWITCH_HAS_CHANGED, true, idx);
      } else {
        triggerEvent(power::SWITCH_HAS_CHANGED, false, idx);
      }
      MutexGuard mg(switcherLock);
      switchChangeArray[idx] = false;
    }
  }
  return returnvalue::OK;
}

object_id_t PcduHandlerDummy::getObjectId() const { return SystemObject::getObjectId(); }

MessageQueueId_t PcduHandlerDummy::getCommandQueue() const { return queue->getId(); }

dur_millis_t PcduHandlerDummy::getPeriodicOperationFrequency() const {
  // TODO: dummy value. Retrieve from intiitalize after task creation..
  return 400;
}

LocalDataPoolManager* PcduHandlerDummy::getHkManagerHandle() { return &manager; }

LocalPoolDataSetBase* PcduHandlerDummy::getDataSetHandle(sid_t sid) { return nullptr; }