#include "message_handler.h"

#include <QDateTime>
#include <cstring>
#include <QString>
#include <QFileInfo>
#include <QMessageLogContext>


static char const *DBG_NAME[] = { "DBG  ", "WARN ", "CRIT ", "FATAL", "INFO " };
static bool installedMsgHandler = false;
static int debugLevel = LOG_NOTICE;

int getDebugLevel() { return debugLevel; }
void setDebugLevel(int newDebugLevel) {
    debugLevel = newDebugLevel;
}

bool messageHandlerInstalled() {
    return installedMsgHandler;
}

QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler) {
    installedMsgHandler = (handler != 0);
    static QtMessageHandler prevHandler = nullptr;
    if (handler) {
        prevHandler = qInstallMessageHandler(handler);
        return prevHandler;
    } else {
        return qInstallMessageHandler(prevHandler);
    }
}

///
/// \brief Print message according to given debug level.
///
/// \note Install this function using qInstallMsgHandler().
///
///  int main(int argc, char **argv) {
///     installMsgHandler(atbDebugOutput);
///     QApplication app(argc, argv);
///     ...
///     return app.exec();
///  }
///
#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
    Q_UNUSED(context);
    QString const localMsg = QString(DBG_NAME[type]) + msg.toLocal8Bit();

    switch (debugLevel) {
        case LOG_DEBUG: { // debug-level message
            syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
        } break;
        case LOG_INFO: { // informational message
            if (type != QtDebugMsg) {
                syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
            }
        } break;
        case LOG_NOTICE: { // normal, but significant, condition
            if (type != QtDebugMsg) {
                syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
            }
        } break;
        case LOG_WARNING: { // warning conditions
            if (type != QtInfoMsg && type != QtDebugMsg) {
                syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
            }
        } break;
        case LOG_ERR: { // error conditions
            if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
                syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
            }
        } break;
        case LOG_CRIT: { // critical conditions
            if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
                syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
            }
        } break;
        case LOG_ALERT: { // action must be taken immediately
            if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
                syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
            }
        } break;
        case LOG_EMERG: { // system is unusable
            if (type != QtInfoMsg && type != QtDebugMsg && type != QtWarningMsg) {
                syslog(LOG_DEBUG, "%s", localMsg.toStdString().c_str());
            }
        } break;
        default: {
            //fprintf(stderr, "%s No ErrorLevel defined! %s\n",
            //    datetime.toStdString().c_str(), msg.toStdString().c_str());
        }
    }
}
#endif