#pragma once
#include <myapp/logging/logger.h>
#include "connection.h"
#include "dataaccess.h"
#include "poll.h"

namespace myapp::modbus {

class device : public std::enable_shared_from_this<device>
{
public:
    virtual ~device() = default;
    virtual void initialize() = 0;

    std::string const& get_name() const noexcept;
    std::string handle_command(std::string) noexcept;
    void status_update_callback(std::function<void(std::string, std::string)>) noexcept;

protected:
    explicit device(std::string name, int slave_id, std::shared_ptr<connection>, std::shared_ptr<logging::logger>);
    virtual std::string handle_command_impl(std::string const&) = 0;
    void raise_status_update(std::string key, std::string value);

    template<typename Derived>
    std::shared_ptr<Derived> shared_from_base()
    {
        return std::static_pointer_cast<Derived>(device::shared_from_this());
    }

    std::string name_;
    int slave_id_;
    std::shared_ptr<data_access> data_access_;
    poll::task_executor_t executor_;
    std::shared_ptr<logging::logger> logger_;
    std::function<void(std::string, std::string)> status_update_callback_;
};

} /* namespace myapp::modbus */
