#pragma once

#include <map>
#include <memory>
#include <thread>

#include "Context.hpp"
#include "behavior/events/types.hpp"
#include "behavior/events/base/BaseEvent.hpp"
#include "behavior/tasks/types.hpp"
#include "behavior/tasks/base/BaseTask.hpp"


/**
 * The Manager.
 * Manage how should the program behave depending on its current state, or the message it receive.
 */
// TODO(Faraphel): could be split in two part.
class Manager {
public:
    Manager(const std::string& address, const std::string& port, bool useIpv6 = false);

    void loop();
    void loopSender();
    void loopReceiver();

private:
    std::thread senderThread;  /// the thread sending communication
    std::thread receiverThread;  /// the thread receiving communication

    std::map<drp::event::EventType, std::shared_ptr<drp::event::BaseEvent>> eventRegistry;  /// hold the event to call depending on the event type
    std::map<drp::task::TaskType, std::shared_ptr<drp::task::BaseTask>> taskRegistry;  /// hold the task to call depending on the server status

    Context context;  /// context used between the events types
};
