#ifndef UTILS_H
#define UTILS_H

//#define DEBUG_RKT_WEBVIEW

#include <string>
#include "rktwebview_global.h"
#include "rktwebview_types.h"

inline std::string basedir(const std::string &path)
{
    int idx1 = static_cast<int>(path.rfind("/"));
    int idx2 = static_cast<int>(path.rfind("\\"));
    std::string r;
    if (idx1 == std::string::npos && idx2 == std::string::npos) {
        r = "";
    } else {
        int idx;
        if (idx1 == std::string::npos) {
            idx = idx2;
        } else if (idx2 == std::string::npos) {
            idx = idx1;
        } else if (idx1 < idx2) {
            idx = idx2;
        } else {
            idx = idx1;
        }
        r = path.substr(0, idx);
    }
    return r;
}
extern "C" {
#ifdef RKTWEBVIEW_PRG_EXE
#undef RKTWEBVIEW_EXPORT
#define RKTWEBVIEW_EXPORT
#endif

RKTWEBVIEW_EXPORT int logLevel();
RKTWEBVIEW_EXPORT void setLogLevel(int l);
RKTWEBVIEW_EXPORT void logElapsed();
RKTWEBVIEW_EXPORT const char *logIndicator(int l);
}

#define LOG_ERROR 1
#define LOG_WARNING 2
#define LOG_INFO 3
#define LOG_DEBUG 4

#define MKLOGSTMT(level, code) if (logLevel() >= level) { fprintf(stderr, "%s: ", logIndicator(level));logElapsed();code;fflush(stderr); }
#define MKL0(level, msg) MKLOGSTMT(level, fprintf(stderr, msg))
#define MKL1(level, msg, a) MKLOGSTMT(level, fprintf(stderr, msg, a))
#define MKL2(level, msg, a, b) MKLOGSTMT(level, fprintf(stderr, msg, a, b))
#define MKL3(level, msg, a, b, c) MKLOGSTMT(level, fprintf(stderr, msg, a, b, c))

#define ERROR0(msg) MKL0(LOG_ERROR, msg)
#define WARN0(msg) MKL0(LOG_WARNING, msg)
#define INFO0(msg)  MKL0(LOG_INFO, msg)
#define DEBUG0(msg) MKL0(LOG_DEBUG, msg)

#define ERROR1(msg, a) MKL1(LOG_ERROR, msg, a)
#define WARN1(msg, a)  MKL1(LOG_WARNING, msg, a)
#define INFO1(msg, a)  MKL1(LOG_INFO, msg, a)
#define DEBUG1(msg, a) MKL1(LOG_DEBUG, msg, a)

#define ERROR2(msg, a, b) MKL2(LOG_ERROR, msg, a, b)
#define WARN2(msg, a, b)  MKL2(LOG_WARNING, msg, a, b)
#define INFO2(msg, a, b)  MKL2(LOG_INFO, msg, a, b)
#define DEBUG2(msg, a, b) MKL2(LOG_DEBUG, msg, a, b)

#define INFO3(msg, a, b, c) MKL3(LOG_INFO, msg, a, b, c)

inline void do_free_data(rkt_data_t *d)
{
    if (d == nullptr) { return; }

    if (d->kind == version) {
        free(d);
    } else if (d->kind == metrics) {
        free(d->data.metrics.log_file);
        free(d);
    } else if (d->kind == event) {
        free(d->data.event.event);
        free(d);
    } else if (d->kind == js_result) {
        free(d->data.js_result.value);
        free(d);
    } else {
        ERROR1("UNEXPECTED: data kind %d cannot be freed\n", d->kind);
    }
}

#endif // UTILS_H
