#ifndef ENGINE_ENGINE_NUMBER_9_MAINLOOP_H
#define ENGINE_ENGINE_NUMBER_9_MAINLOOP_H

#include "baza.h"
#include <functional>
#include <sys/time.h>
#include "os_utils.h"
#include "http_structures/client_request.h"
#include <stdint.h>

namespace een9 {
    struct ConnectionInfo {
        // todo: add server address field
        // todo: add client address field
        int type; // O_o why??
    };

    /* This structure is passed to guest function. It contains server info that might be or might be not used
     * by guest */
    struct EEN9_ServerTips {
        size_t server_load;
        size_t critical_load_1;
        timeval recommended_timeout;
    };

    struct SlaveTask {
        ConnectionInfo conn_info;
        UniqueFdWrapper fd;
        EEN9_ServerTips s_tips;
    };

    typedef int worker_id_t;

    /* guest_core function must not throw anything that is not derived from std::exception */
    typedef std::function<std::string(const SlaveTask&, const ClientRequest&, worker_id_t worker_id)> guest_core_t;

    struct ServersConfiguration {
        size_t critical_load_1 = 90;
        size_t critical_load_2 = 100;

        timeval request_timeout{20, 0};
    };

    struct MainloopParameters {
        bool do_logging = true;
        bool open_admin_listener = true;
        // todo: add support for unix socket address
        uint16_t admin_listener_port = 12345;
        guest_core_t guest_core;
        size_t slave_number = 2;
        std::vector<uint16_t> ports_to_listen;
        int mainloop_recheck_interval_us = 100;

        ServersConfiguration s_conf;
    };

    void electric_boogaloo(const MainloopParameters& params, bool& termination_trigger);
}

#endif