#include "foundation/diagnostics/OnceLogger.h"

#include <mutex>
#include <unordered_set>

#include "foundation/diagnostics/Logger.h"

namespace
{
    std::mutex g_mutex;
    std::unordered_set<std::string> g_seen;

    bool first(std::string_view level, std::string_view channel, const std::string& key)
    {
        std::string identity;
        identity.reserve(level.size() + channel.size() + key.size() + 2);
        identity.append(level);
        identity.push_back(':');
        identity.append(channel);
        identity.push_back(':');
        identity.append(key);

        std::lock_guard lock(g_mutex);
        return g_seen.insert(std::move(identity)).second;
    }
}

namespace ta::foundation::diagnostics
{
    void OnceLogger::trace(const std::string_view channel, std::string key, std::string message)
    {
        if (first("trace", channel, key))
            ta::foundation::logger::trace(std::string(channel), std::move(message));
    }

    void OnceLogger::info(const std::string_view channel, std::string key, std::string message)
    {
        if (first("info", channel, key))
            ta::foundation::logger::info(std::string(channel), std::move(message));
    }

    void OnceLogger::warn(const std::string_view channel, std::string key, std::string message)
    {
        if (first("warn", channel, key))
            ta::foundation::logger::warn(std::string(channel), std::move(message));
    }

    void OnceLogger::error(const std::string_view channel, std::string key, std::string message)
    {
        if (first("error", channel, key))
            ta::foundation::logger::error(std::string(channel), std::move(message));
    }

    void OnceLogger::reset()
    {
        std::lock_guard lock(g_mutex);
        g_seen.clear();
    }
}
