#ifndef RTLogger_hpp
#define RTLogger_hpp

#include <atomic>
#include <memory>
#include <string>
#include <thread>
#include <MPMCQueue.h>
#include <semaphore>

class RTLogger {
public:
    static RTLogger& get();
    
    static void log(const char* format, ...);
private:
    struct message {
        message(std::string && s) noexcept: shouldExit(false), val(std::move(s)) { }
        message() noexcept: shouldExit(true) { }
        bool shouldExit;
        std::string val;
    };
    RTLogger();
    ~RTLogger();
    RTLogger(const RTLogger&) = delete;
    
    void start();
    void stop();
    
    std::unique_ptr<std::thread> thread;
    rigtorp::MPMCQueue<message> q;
    std::counting_semaphore<1024> sema;
    
    static std::atomic<RTLogger*> instance;
    static_assert(decltype(instance)::is_always_lock_free);
    
    friend class RTLoggerThread;
};

#endif /* RTLogger_hpp */
