#ifndef MISSION_CONTROLLER_THERMALCONTROLLER_H_
#define MISSION_CONTROLLER_THERMALCONTROLLER_H_

#include <fsfw/controller/ExtendedControllerBase.h>
#include <fsfw/timemanager/Countdown.h>
#include <mission/controller/controllerdefinitions/ThermalControllerDefinitions.h>
#include <mission/devices/devicedefinitions/Max31865Definitions.h>
#include <mission/devices/devicedefinitions/SusDefinitions.h>
#include <mission/devices/devicedefinitions/Tmp1075Definitions.h>

class ThermalController : public ExtendedControllerBase {
 public:
  static const uint16_t INVALID_TEMPERATURE = 999;

  ThermalController(object_id_t objectId);

  ReturnValue_t initialize() override;

 protected:
  virtual ReturnValue_t handleCommandMessage(CommandMessage* message) override;
  virtual void performControlOperation() override;
  virtual ReturnValue_t initializeLocalDataPool(localpool::DataPool& localDataPoolMap,
                                                LocalDataPoolManager& poolManager) override;
  virtual LocalPoolDataSetBase* getDataSetHandle(sid_t sid) override;

  // Mode abstract functions
  virtual ReturnValue_t checkModeCommand(Mode_t mode, Submode_t submode,
                                         uint32_t* msToReachTheMode) override;

 private:
  static const uint32_t DELAY = 500;

  enum class InternalState { STARTUP, INITIAL_DELAY, READY };

  InternalState internalState = InternalState::STARTUP;

  thermalControllerDefinitions::SensorTemperatures sensorTemperatures;
  thermalControllerDefinitions::SusTemperatures susTemperatures;
  thermalControllerDefinitions::DeviceTemperatures deviceTemperatures;

  // Temperature Sensors
  MAX31865::Max31865Set max31865Set0;
  MAX31865::Max31865Set max31865Set1;
  MAX31865::Max31865Set max31865Set2;
  MAX31865::Max31865Set max31865Set3;
  MAX31865::Max31865Set max31865Set4;
  MAX31865::Max31865Set max31865Set5;
  MAX31865::Max31865Set max31865Set6;
  MAX31865::Max31865Set max31865Set7;
  MAX31865::Max31865Set max31865Set8;
  MAX31865::Max31865Set max31865Set9;
  MAX31865::Max31865Set max31865Set10;
  MAX31865::Max31865Set max31865Set11;
  MAX31865::Max31865Set max31865Set12;
  MAX31865::Max31865Set max31865Set13;
  MAX31865::Max31865Set max31865Set14;
  MAX31865::Max31865Set max31865Set15;
  TMP1075::Tmp1075Dataset tmp1075SetTcs0;
  TMP1075::Tmp1075Dataset tmp1075SetTcs1;
  TMP1075::Tmp1075Dataset tmp1075SetPlPcdu0;
  TMP1075::Tmp1075Dataset tmp1075SetPlPcdu1;
  TMP1075::Tmp1075Dataset tmp1075SetIfBoard;

  // SUS
  SUS::SusDataset susSet0;
  SUS::SusDataset susSet1;
  SUS::SusDataset susSet2;
  SUS::SusDataset susSet3;
  SUS::SusDataset susSet4;
  SUS::SusDataset susSet5;
  SUS::SusDataset susSet6;
  SUS::SusDataset susSet7;
  SUS::SusDataset susSet8;
  SUS::SusDataset susSet9;
  SUS::SusDataset susSet10;
  SUS::SusDataset susSet11;

  // Initial delay to make sure all pool variables have been initialized their owners
  Countdown initialCountdown = Countdown(DELAY);

  PoolEntry<float> tmp1075Tcs0 = PoolEntry<float>(10.0);
  PoolEntry<float> tmp1075Tcs1 = PoolEntry<float>(10.0);
  PoolEntry<float> tmp1075PlPcdu0 = PoolEntry<float>(10.0);
  PoolEntry<float> tmp1075PlPcdu1 = PoolEntry<float>(10.0);
  PoolEntry<float> tmp1075IfBrd = PoolEntry<float>(10.0);

  static constexpr dur_millis_t MUTEX_TIMEOUT = 50;
  void copySensors();
  void copySus();
  void copyDevices();
};

#endif /* MISSION_CONTROLLER_THERMALCONTROLLER_H_ */