#include "SyrlinksAssembly.h"

#include <eive/objects.h>
#include <mission/com/defs.h>

using namespace returnvalue;

SyrlinksAssembly::SyrlinksAssembly(object_id_t objectId) : AssemblyBase(objectId) {
  ModeListEntry entry;
  entry.setObject(objects::SYRLINKS_HANDLER);
  entry.setMode(MODE_OFF);
  entry.setSubmode(SUBMODE_NONE);
  commandTable.insert(entry);
}

ReturnValue_t SyrlinksAssembly::commandChildren(Mode_t mode, Submode_t submode) {
  commandTable[0].setMode(mode);
  commandTable[0].setSubmode(submode);
  HybridIterator<ModeListEntry> iter(commandTable.begin(), commandTable.end());
  if (recoveryState == RECOVERY_IDLE) {
    ReturnValue_t result = checkAndHandleHealthState(mode, submode);
    if (result == NEED_TO_CHANGE_HEALTH) {
      return result;
    }
  }
  executeTable(iter);
  return returnvalue::OK;
}

ReturnValue_t SyrlinksAssembly::checkChildrenStateOn(Mode_t wantedMode, Submode_t wantedSubmode) {
  if (childrenMap[objects::SYRLINKS_HANDLER].mode != wantedMode) {
    return NOT_ENOUGH_CHILDREN_IN_CORRECT_STATE;
  }
  return returnvalue::OK;
}

ReturnValue_t SyrlinksAssembly::isModeCombinationValid(Mode_t mode, Submode_t submode) {
  if (mode == MODE_ON or mode == DeviceHandlerIF::MODE_NORMAL) {
    if (submode >= com::Submode::NUM_SUBMODES or submode < com::Submode::RX_ONLY) {
      return HasModesIF::INVALID_SUBMODE;
    }
    return returnvalue::OK;
  }
  if (mode == MODE_OFF and submode != SUBMODE_NONE) {
    return HasModesIF::INVALID_SUBMODE;
  }
  return returnvalue::OK;
}

ReturnValue_t SyrlinksAssembly::checkAndHandleHealthState(Mode_t deviceMode,
                                                          Submode_t deviceSubmode) {
  HealthState health = healthHelper.healthTable->getHealth(objects::SYRLINKS_HANDLER);
  if (health == FAULTY or health == PERMANENT_FAULTY) {
    overwriteDeviceHealth(objects::SYRLINKS_HANDLER, health);
    return NEED_TO_CHANGE_HEALTH;
  } else if (health == EXTERNAL_CONTROL) {
    modeHelper.setForced(true);
  }
  return OK;
}

void SyrlinksAssembly::handleChildrenLostMode(ReturnValue_t result) {
  startTransition(mode, submode);
}