#pragma once

#include <cstdint>
#include <map>
#include <memory>

#include "profinet_serv_data.hpp"
#include "profinet_subslot.hpp"
#include "profinet_module.hpp"

class ProfinetSlot 
{
public:
   /**
    * @brief Construct a new Profinet Slot object
    * 
    * @param slot_nbr номер слота
    */
   ProfinetSlot(uint16_t slot_nbr);
   /**
    * @brief Подключает модуль к слоту
    * 
    * @param pnet_data Данные pnet
    * @return true модуль подключен
    * @return false модуль не подключен
    */
   bool plugModule(ProfinetServiceData& pnet_data, std::shared_ptr<ProfinetModule>& module_ptr);
   /**
    * @brief Отключает модуль от слота 
    * 
    * @param pnet_data Данные pnet
    * @return true модуль был поключен и теперь отключен
    * @return false модуль не был подключен
    */
   bool pullModule(ProfinetServiceData& pnet_data);

   /**
    * @brief Добавляет ранее созданный подслот subslot_ptr
    * 
    * @param subslot_ptr подслот
    * @return true подслот добавлен
    * @return false подслот был добавлен ранее
    */
   bool addSubslot(std::shared_ptr<ProfinetSubslot>& subslot_ptr);

   /**
    * @brief Если подслот с номером subslot_nbr еще не добавлен, то создает подслот и добавляет его
    * 
    * @param subslot_nbr номер подслота
    * @return std::shared_ptr<ProfinetSubslot> указатель на подслот
    */
   std::shared_ptr<ProfinetSubslot> addSubslot(uint16_t subslot_nbr);

   std::shared_ptr<ProfinetSubslot> getSubslotPtr(uint16_t subslot_nbr);

   std::shared_ptr<ProfinetModule> getModulePtr();

   std::map<uint16_t, std::shared_ptr<ProfinetSubslot>>& getSubslotsPtr() { return m_subslots; };

public:   
   /// Номер слота
   const uint16_t m_slot_nbr;

private:
   /// Модуль вставленный в этот слот
   std::shared_ptr<ProfinetModule> m_module_ptr;

   /// множество подслотов
   std::map<uint16_t, std::shared_ptr<ProfinetSubslot>> m_subslots;  
};