/*
 * log.h
 *
 * Copyright (C) 2018 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef _LOG_H_
#define _LOG_H_

#include <sdk/defs.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>

#define MAX_LOG_MESSAGE_SIZE 256

#ifdef DEBUG
#define TRACE(x, ...) log_write(LOG_DEBUG, x, ##__VA_ARGS__)
#else
#define TRACE(x, ...)
#endif

/* For compatibility: */
#define FTRACE TRACE

typedef enum
{
    LOG_DEBUG,
    LOG_NORMAL,
    LOG_WARNING,
    LOG_ERROR,
    LOG_CRITICAL,
} log_level_t;

extern char *debug_channel;
extern log_level_t debug_min_level;

void append_log_entry(const char *source, log_level_t level, const char *message);

static inline void log_write(log_level_t level, const char *format, ...)
{
    extern const char driver_name[];
    static char log_buffer[MAX_LOG_MESSAGE_SIZE] = "";

    va_list ap;
    va_start(ap, format);

    size_t length = vsnprintf(NULL, 0, format, ap);
    char message[length + 1];
    vsnprintf(message, length + 1, format, ap);

    va_end(ap);

    char *ptr = message;
    while (*ptr)
    {
        char *end = strchr(ptr, '\n');
        if (end) *end = '\0';
        else break;

        char full_message[strlen(log_buffer) + strlen(ptr) + 1];
        strcpy(full_message, log_buffer);
        strcat(full_message, ptr);
        append_log_entry(driver_name, level, full_message);
        *log_buffer = '\0';

        ptr = end + 1;
    }

    strncat(log_buffer, ptr, sizeof(log_buffer) - strlen(log_buffer) - 1);
}

#endif
