#pragma once

#include <cstdint>
#include <vector>

class ProfinetIface {
public:
    enum ErrorCode {
        ERR_SUCCESS                  =  0,
        ERR_MODULE_DOES_NOT_EXIST    = -1,
        ERR_SUBMODULE_DOES_NOT_EXIST = -2,
        ERR_PARAM_DOES_NOT_EXIST     = -3,
        ERR_WRONG_DATA_LENGTH        = -4
    };
    
    enum Events
    {
        EVENT_CONNECTION_ESTABLISHED = 0x00000001, /// Установлено соединение с ПЛК
        EVENT_NEW_CYCLIC_DATA        = 0x00000002, /// Получение новых циклических данных от ПЛК
        EVENT_NEW_PARAM_DATA         = 0x00000004, /// Новая запись параметра от ПЛК
        EVENT_CONNECTION_ABORT       = 0x00000008
    };

    /**
     * @brief Прочитать циклические данные от ПЛК
     * 
     * @param module_id 
     * @param submodule_id 
     * @param p_data 
     * @return true 
     * @return false 
     */
    virtual int getOutputCyclicData(uint32_t module_id, 
                                    uint32_t submodule_id, 
                                    std::vector<uint8_t>& data) = 0;
    /**
     * @brief Записать циклические данные к ПЛК
     * 
     * @param module_id 
     * @param submodule_id 
     * @param data 
     * @return int 
     */
    virtual int putInputCyclicData(uint32_t module_id, 
                                   uint32_t submodule_id, 
                                   std::vector<uint8_t>& data) = 0;
    /**
     * @brief Прочитать параметры подмодуля
     * 
     * @param module_id 
     * @param submodule_id 
     * @param param_id 
     * @param data 
     * @return int 
     */
    virtual int getSubmoduleParam(uint32_t module_id, 
                                  uint32_t submodule_id, 
                                  uint32_t param_id, 
                                  std::vector<uint8_t>& data) = 0;
    /**
     * @brief Прочитать флаги событий
     * 
     * @return uint32_t 
     */
    virtual uint32_t getEvents() const = 0;
    
    /**
     * @brief Сбросить флаги событий
     * 
     * @return uint32_t 
     */
    virtual void clearEvents(uint32_t mask) = 0;
};