// SPDX-FileCopyrightText: 2024 Yury Gubich <blue@macaw.me>
// SPDX-License-Identifier: GPL-3.0-or-later

#include "core.h"

#include "connection/connection.h"

Core::Core(const std::string& configPath):
    config(configPath),
    logger(config.getLogLevel()),
    router(logger),
    initialized(false)
{}

void Core::send(const std::string& jid, const std::string& body) {
    std::shared_ptr<Connection> cn = connection.lock();
    if (!cn) {
        logger.log(Shared::Logger::warning, "Couldn't send a message to " + jid + ", connection is not available", {"Core"});
        return;
    }

    cn->send(jid, body);
}

void Core::initialize(const std::shared_ptr<Connection>& cn) {
    connection = cn;
    router.setConnection(cn);

    if (initialized)
        return;

    initializeActors();
    initializeResponses();

    initialized = true;
}

void Core::setGroup(const std::string& jid, const std::string& group) {
    router.registerActor(jid, group);

    Shared::VC actors = router.getActors();
    std::string defaultGroup = router.getDefaultGroup();

    for (Shared::VC::const_iterator itr = actors.begin(); itr != actors.end(); )
        if (itr->second == defaultGroup)
            itr = actors.erase(itr);
        else
            itr++;

    actors["default"] = defaultGroup;
    config.setActors(actors);
}

void Core::publish(const std::string& service, const std::string& node, const std::string& title, const std::string& body) {
    std::shared_ptr<Connection> cn = connection.lock();
    if (!cn) {
        logger.log(Shared::Logger::warning, "Couldn't publish to " + node + "@" + service + ", connection is not available", {"Core"});
        return;
    }

    cn->publish(service, node, title, body);
}

void Core::initializeActors() {
    for (const std::pair<const std::string, std::string>& pair : config.getActors()) {
        logger.log(Shared::Logger::info, "registering actor " + pair.first + " as " + pair.second, {"Core"});
        router.registerActor(pair.first, pair.second);
    }
}

void Core::initializeResponses() {
    for (const std::pair<Shared::Result, Shared::Strings>& pair : config.getResponses())
        router.setResponses(pair.first, pair.second);
}