#ifndef MISSION_CONTROLLER_CONTROLLERDEFINITIONS_THERMALCONTROLLERDEFINITIONS_H_
#define MISSION_CONTROLLER_CONTROLLERDEFINITIONS_THERMALCONTROLLERDEFINITIONS_H_

#include <fsfw/datapoollocal/LocalPoolVariable.h>
#include <fsfw/datapoollocal/StaticLocalDataSet.h>

namespace thermalControllerDefinitions {

enum SetIds : uint32_t {
  SENSOR_TEMPERATURES,
  DEVICE_TEMPERATURES,
  SUS_TEMPERATURES,
  COMPONENT_TEMPERATURES
};

enum PoolIds : lp_id_t {
  SENSOR_PLOC_HEATSPREADER,
  SENSOR_PLOC_MISSIONBOARD,
  SENSOR_4K_CAMERA,
  SENSOR_DAC_HEATSPREADER,
  SENSOR_STARTRACKER,
  SENSOR_RW1,
  SENSOR_DRO,
  SENSOR_SCEX,
  SENSOR_X8,
  SENSOR_HPA,
  SENSOR_TX_MODUL,
  SENSOR_MPA,
  SENSOR_ACU,
  SENSOR_PLPCDU_HEATSPREADER,
  SENSOR_TCS_BOARD,
  SENSOR_MAGNETTORQUER,
  SENSOR_TMP1075_TCS_0,
  SENSOR_TMP1075_TCS_1,
  SENSOR_TMP1075_PLPCDU_0,
  SENSOR_TMP1075_PLPCDU_1,
  SENSOR_TMP1075_IF_BOARD,

  SUS_0_N_LOC_XFYFZM_PT_XF,
  SUS_6_R_LOC_XFYBZM_PT_XF,
  SUS_1_N_LOC_XBYFZM_PT_XB,
  SUS_7_R_LOC_XBYBZM_PT_XB,
  SUS_2_N_LOC_XFYBZB_PT_YB,
  SUS_8_R_LOC_XBYBZB_PT_YB,
  SUS_3_N_LOC_XFYBZF_PT_YF,
  SUS_9_R_LOC_XBYBZB_PT_YF,
  SUS_4_N_LOC_XMYFZF_PT_ZF,
  SUS_10_N_LOC_XMYBZF_PT_ZF,
  SUS_5_N_LOC_XFYMZB_PT_ZB,
  SUS_11_R_LOC_XBYMZB_PT_ZB,

  COMPONENT_RW,

  TEMP_Q7S,
  BATTERY_TEMP_1,
  BATTERY_TEMP_2,
  BATTERY_TEMP_3,
  BATTERY_TEMP_4,
  TEMP_RW1,
  TEMP_RW2,
  TEMP_RW3,
  TEMP_RW4,
  TEMP_STAR_TRACKER,
  TEMP_SYRLINKS_POWER_AMPLIFIER,
  TEMP_SYRLINKS_BASEBAND_BOARD,
  TEMP_MGT,
  TEMP_ACU,
  TEMP_PDU1,
  TEMP_PDU2,
  TEMP_1_P60DOCK,
  TEMP_2_P60DOCK,
  TEMP_GYRO_0_SIDE_A,
  TEMP_GYRO_1_SIDE_A,
  TEMP_GYRO_2_SIDE_B,
  TEMP_GYRO_3_SIDE_B,
  TEMP_MGM_0_SIDE_A,
  TEMP_MGM_2_SIDE_B,
  TEMP_ADC_PAYLOAD_PCDU
};

static const uint8_t ENTRIES_SENSOR_TEMPERATURE_SET = 25;
static const uint8_t ENTRIES_DEVICE_TEMPERATURE_SET = 25;
static const uint8_t ENTRIES_SUS_TEMPERATURE_SET = 12;

/**
 * @brief   This dataset can be used to store the collected temperatures of all temperature sensors
 */
class SensorTemperatures : public StaticLocalDataSet<ENTRIES_SENSOR_TEMPERATURE_SET> {
 public:
  SensorTemperatures(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SENSOR_TEMPERATURES) {}

  SensorTemperatures(object_id_t objectId)
      : StaticLocalDataSet(sid_t(objectId, SENSOR_TEMPERATURES)) {}

  lp_var_t<float> sensor_ploc_heatspreader =
      lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLOC_HEATSPREADER, this);
  lp_var_t<float> sensor_ploc_missionboard =
      lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLOC_MISSIONBOARD, this);
  lp_var_t<float> sensor_4k_camera = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_4K_CAMERA, this);
  lp_var_t<float> sensor_dac_heatspreader =
      lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DAC_HEATSPREADER, this);
  lp_var_t<float> sensor_startracker =
      lp_var_t<float>(sid.objectId, PoolIds::SENSOR_STARTRACKER, this);
  lp_var_t<float> sensor_rw1 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_RW1, this);
  lp_var_t<float> sensor_dro = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_DRO, this);
  lp_var_t<float> sensor_scex = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_SCEX, this);
  lp_var_t<float> sensor_x8 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_X8, this);
  lp_var_t<float> sensor_hpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_HPA, this);
  lp_var_t<float> sensor_tx_modul = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TX_MODUL, this);
  lp_var_t<float> sensor_mpa = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MPA, this);
  lp_var_t<float> sensor_acu = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_ACU, this);
  lp_var_t<float> sensor_plpcdu_heatspreader =
      lp_var_t<float>(sid.objectId, PoolIds::SENSOR_PLPCDU_HEATSPREADER, this);
  lp_var_t<float> sensor_tcs_board = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TCS_BOARD, this);
  lp_var_t<float> sensor_magnettorquer =
      lp_var_t<float>(sid.objectId, PoolIds::SENSOR_MAGNETTORQUER, this);
  lp_var_t<float> tmp1075Tcs0 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TMP1075_TCS_0, this);
  lp_var_t<float> tmp1075Tcs1 = lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TMP1075_TCS_1, this);
  lp_var_t<float> tmp1075PlPcdu0 =
      lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TMP1075_PLPCDU_0, this);
  lp_var_t<float> tmp1075PlPcdu1 =
      lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TMP1075_PLPCDU_1, this);
  lp_var_t<float> tmp1075IfBrd =
      lp_var_t<float>(sid.objectId, PoolIds::SENSOR_TMP1075_IF_BOARD, this);
};

/**
 * @brief   This dataset can be used to store the collected temperatures of all device temperature
 *          sensors
 */
class DeviceTemperatures : public StaticLocalDataSet<ENTRIES_DEVICE_TEMPERATURE_SET> {
 public:
  DeviceTemperatures(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, DEVICE_TEMPERATURES) {}

  DeviceTemperatures(object_id_t objectId)
      : StaticLocalDataSet(sid_t(objectId, DEVICE_TEMPERATURES)) {}

  lp_var_t<float> q7s = lp_var_t<float>(sid.objectId, PoolIds::TEMP_Q7S, this);
  lp_var_t<int16_t> batteryTemp1 = lp_var_t<int16_t>(sid.objectId, PoolIds::BATTERY_TEMP_1, this);
  lp_var_t<int16_t> batteryTemp2 = lp_var_t<int16_t>(sid.objectId, PoolIds::BATTERY_TEMP_2, this);
  lp_var_t<int16_t> batteryTemp3 = lp_var_t<int16_t>(sid.objectId, PoolIds::BATTERY_TEMP_3, this);
  lp_var_t<int16_t> batteryTemp4 = lp_var_t<int16_t>(sid.objectId, PoolIds::BATTERY_TEMP_4, this);
  lp_var_t<int32_t> rw1 = lp_var_t<int32_t>(sid.objectId, PoolIds::TEMP_RW1, this);
  lp_var_t<int32_t> rw2 = lp_var_t<int32_t>(sid.objectId, PoolIds::TEMP_RW2, this);
  lp_var_t<int32_t> rw3 = lp_var_t<int32_t>(sid.objectId, PoolIds::TEMP_RW3, this);
  lp_var_t<int32_t> rw4 = lp_var_t<int32_t>(sid.objectId, PoolIds::TEMP_RW4, this);
  lp_var_t<float> startracker = lp_var_t<float>(sid.objectId, PoolIds::TEMP_STAR_TRACKER, this);
  lp_var_t<float> syrlinksPowerAmplifier =
      lp_var_t<float>(sid.objectId, PoolIds::TEMP_SYRLINKS_POWER_AMPLIFIER, this);
  lp_var_t<float> syrlinksBasebandBoard =
      lp_var_t<float>(sid.objectId, PoolIds::TEMP_SYRLINKS_BASEBAND_BOARD, this);
  lp_var_t<int16_t> mgt = lp_var_t<int16_t>(sid.objectId, PoolIds::TEMP_MGT, this);
  lp_vec_t<float, 3> acu = lp_vec_t<float, 3>(sid.objectId, PoolIds::TEMP_ACU, this);
  lp_var_t<float> pdu1 = lp_var_t<float>(sid.objectId, PoolIds::TEMP_PDU1, this);
  lp_var_t<float> pdu2 = lp_var_t<float>(sid.objectId, PoolIds::TEMP_PDU2, this);
  lp_var_t<float> temp1P60dock = lp_var_t<float>(sid.objectId, PoolIds::TEMP_1_P60DOCK, this);
  lp_var_t<float> temp2P60dock = lp_var_t<float>(sid.objectId, PoolIds::TEMP_2_P60DOCK, this);
  lp_var_t<float> gyro0SideA = lp_var_t<float>(sid.objectId, PoolIds::TEMP_GYRO_0_SIDE_A, this);
  lp_var_t<float> gyro1SideA = lp_var_t<float>(sid.objectId, PoolIds::TEMP_GYRO_1_SIDE_A, this);
  lp_var_t<float> gyro2SideB = lp_var_t<float>(sid.objectId, PoolIds::TEMP_GYRO_2_SIDE_B, this);
  lp_var_t<float> gyro3SideB = lp_var_t<float>(sid.objectId, PoolIds::TEMP_GYRO_3_SIDE_B, this);
  lp_var_t<float> mgm0SideA = lp_var_t<float>(sid.objectId, PoolIds::TEMP_MGM_0_SIDE_A, this);
  lp_var_t<float> mgm2SideB = lp_var_t<float>(sid.objectId, PoolIds::TEMP_MGM_2_SIDE_B, this);
  lp_var_t<float> adcPayloadPcdu =
      lp_var_t<float>(sid.objectId, PoolIds::TEMP_ADC_PAYLOAD_PCDU, this);
};

/**
 * @brief   This dataset can be used to store the collected temperatures of all SUS temperature
 * sensors
 */
class SusTemperatures : public StaticLocalDataSet<ENTRIES_SUS_TEMPERATURE_SET> {
 public:
  SusTemperatures(HasLocalDataPoolIF* owner) : StaticLocalDataSet(owner, SUS_TEMPERATURES) {}

  SusTemperatures(object_id_t objectId) : StaticLocalDataSet(sid_t(objectId, SUS_TEMPERATURES)) {}

  lp_var_t<float> sus_0_n_loc_xfyfzm_pt_xf =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_0_N_LOC_XFYFZM_PT_XF, this);
  lp_var_t<float> sus_6_r_loc_xfybzm_pt_xf =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_6_R_LOC_XFYBZM_PT_XF, this);
  lp_var_t<float> sus_1_n_loc_xbyfzm_pt_xb =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_1_N_LOC_XBYFZM_PT_XB, this);
  lp_var_t<float> sus_7_r_loc_xbybzm_pt_xb =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_7_R_LOC_XBYBZM_PT_XB, this);
  lp_var_t<float> sus_2_n_loc_xfybzb_pt_yb =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_2_N_LOC_XFYBZB_PT_YB, this);
  lp_var_t<float> sus_8_r_loc_xbybzb_pt_yb =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_8_R_LOC_XBYBZB_PT_YB, this);
  lp_var_t<float> sus_3_n_loc_xfybzf_pt_yf =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_3_N_LOC_XFYBZF_PT_YF, this);
  lp_var_t<float> sus_9_r_loc_xbybzb_pt_yf =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_9_R_LOC_XBYBZB_PT_YF, this);
  lp_var_t<float> sus_4_n_loc_xmyfzf_pt_zf =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_4_N_LOC_XMYFZF_PT_ZF, this);
  lp_var_t<float> sus_10_n_loc_xmybzf_pt_zf =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_10_N_LOC_XMYBZF_PT_ZF, this);
  lp_var_t<float> sus_5_n_loc_xfymzb_pt_zb =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_5_N_LOC_XFYMZB_PT_ZB, this);
  lp_var_t<float> sus_11_r_loc_xbymzb_pt_zb =
      lp_var_t<float>(sid.objectId, PoolIds::SUS_11_R_LOC_XBYMZB_PT_ZB, this);
};

}  // namespace thermalControllerDefinitions

#endif /* MISSION_CONTROLLER_CONTROLLERDEFINITIONS_THERMALCONTROLLERDEFINITIONS_H_ */