#include "callbacks.h"

namespace {
    void ReleasePyObject(PyObject* obj) {
        PyGILState_STATE state = PyGILState_Ensure();
        Py_XDECREF(obj);
        PyGILState_Release(state);
    }

    std::shared_ptr<PyObject> MakePyObjectPtr(PyObject* obj) {
        Py_XINCREF(obj);
        std::shared_ptr<PyObject> ptr(obj, &ReleasePyObject);
        return ptr;
    }

    template <typename ...Types>
    std::function<void (Types...)> MakePyCallback(void (*callback)(PyObject*, Types...), PyObject* object) {
        auto ptr(MakePyObjectPtr(object));
        return [=](Types...args) { callback(ptr.get(), std::forward<Types>(args)...); };
    }
}

namespace NSaas {
    TWriteCallback MakeWriteCallback(TCWriteCallback callback, PyObject* future) {
        return MakePyCallback(callback, future);
    }

    TPythonLogger::TPythonLogger(TPyLoggerCallback callback, PyObject* object, int logLevel)
        : Callback(callback)
        , Object(MakePyObjectPtr(object))
        , LogLevel(logLevel)
    {}

    void TPythonLogger::Log(const TString& msg, const TString& sourceId, const TString& sessionId, int level) {
        if (IsEnabled(level)) {
            Callback(Object.get(), msg, sourceId, sessionId, level);
        }
    }

    bool TPythonLogger::IsEnabled(int level) const {
        return level <= LogLevel;
    }
}
