#include "ObjectFactory.h"

#include <fsfw/tmtcservices/CommandingServiceBase.h>
#include <fsfw/tmtcservices/PusServiceBase.h>
#include <mission/controller/ThermalController.h>
#include <mission/core/GenericFactory.h>
#include <mission/tmtc/TmFunnel.h>
#include <objects/systemObjectList.h>
#include <tmtc/pusIds.h>

#include "OBSWConfig.h"
#include "eive/definitions.h"
#include "fsfw_tests/integration/task/TestTask.h"

#if OBSW_USE_TMTC_TCP_BRIDGE == 0
#include "fsfw/osal/common/UdpTcPollingTask.h"
#include "fsfw/osal/common/UdpTmTcBridge.h"
#else
#include "fsfw/osal/common/TcpTmTcBridge.h"
#include "fsfw/osal/common/TcpTmTcServer.h"
#endif

#include <fsfw/tmtcpacket/pus/tm.h>

#if OBSW_ADD_TEST_CODE == 1
#include <test/testtasks/TestTask.h>
#endif

#include <dummies/AcuDummy.h>
#include <dummies/BpxDummy.h>
#include <dummies/ComCookieDummy.h>
#include <dummies/ComIFDummy.h>
#include <dummies/CoreControllerDummy.h>
#include <dummies/GyroAdisDummy.h>
#include <dummies/GyroL3GD20Dummy.h>
#include <dummies/ImtqDummy.h>
#include <dummies/MgmLIS3MDLDummy.h>
#include <dummies/P60DockDummy.h>
#include <dummies/PduDummy.h>
#include <dummies/PlPcduDummy.h>
#include <dummies/RwDummy.h>
#include <dummies/StarTrackerDummy.h>
#include <dummies/SusDummy.h>
#include <dummies/SyrlinksDummy.h>
#include <dummies/TemperatureSensorsDummy.h>

#include "mission/utility/GlobalConfigHandler.h"

void Factory::setStaticFrameworkObjectIds() {
  PusServiceBase::PUS_DISTRIBUTOR = objects::PUS_PACKET_DISTRIBUTOR;
  PusServiceBase::PACKET_DESTINATION = objects::TM_FUNNEL;

  CommandingServiceBase::defaultPacketSource = objects::PUS_PACKET_DISTRIBUTOR;
  CommandingServiceBase::defaultPacketDestination = objects::TM_FUNNEL;

  TmFunnel::downlinkDestination = objects::TMTC_BRIDGE;
  // No storage object for now.
  TmFunnel::storageDestination = objects::NO_OBJECT;

  VerificationReporter::DEFAULT_RECEIVER = objects::PUS_SERVICE_1_VERIFICATION;
}

void ObjectFactory::produce(void* args) {
  Factory::setStaticFrameworkObjectIds();
  ObjectFactory::produceGenericObjects();

  new ComIFDummy(objects::DUMMY_COM_IF);
  ComCookieDummy* comCookieDummy = new ComCookieDummy();
  new BpxDummy(objects::BPX_BATT_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new CoreControllerDummy(objects::CORE_CONTROLLER);
  new RwDummy(objects::RW1, objects::DUMMY_COM_IF, comCookieDummy);
  new RwDummy(objects::RW2, objects::DUMMY_COM_IF, comCookieDummy);
  new RwDummy(objects::RW3, objects::DUMMY_COM_IF, comCookieDummy);
  new RwDummy(objects::RW4, objects::DUMMY_COM_IF, comCookieDummy);
  new StarTrackerDummy(objects::STAR_TRACKER, objects::DUMMY_COM_IF, comCookieDummy);
  new SyrlinksDummy(objects::SYRLINKS_HK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new ImtqDummy(objects::IMTQ_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new AcuDummy(objects::ACU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new PduDummy(objects::PDU1_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new PduDummy(objects::PDU2_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new P60DockDummy(objects::P60DOCK_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new GyroAdisDummy(objects::GYRO_0_ADIS_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new GyroL3GD20Dummy(objects::GYRO_1_L3G_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new GyroAdisDummy(objects::GYRO_2_ADIS_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new GyroL3GD20Dummy(objects::GYRO_3_L3G_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new MgmLIS3MDLDummy(objects::MGM_0_LIS3_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new MgmLIS3MDLDummy(objects::MGM_2_LIS3_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new PlPcduDummy(objects::PLPCDU_HANDLER, objects::DUMMY_COM_IF, comCookieDummy);
  new TemperatureSensorsDummy();
  new SusDummy();
  new ThermalController(objects::THERMAL_CONTROLLER, objects::NO_OBJECT);
  new TestTask(objects::TEST_TASK);
}