/**
 * @file log.c
 * @author Radek Krejci <rkrejci@cesnet.cz>
 * @brief libnetconf2 - log functions
 *
 * @copyright
 * Copyright (c) 2015 - 2021 CESNET, z.s.p.o.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#define _GNU_SOURCE /* pthread_rwlock_t */

#include <stdarg.h>
#include <stdio.h>

#include <libyang/libyang.h>

#ifdef NC_ENABLED_SSH
    #include <libssh/libssh.h>
#endif

#include "compat.h"
#include "libnetconf.h"
#include "log.h"

/**
 * @brief libnetconf verbose level variable
 */
ATOMIC_T verbose_level = 0;

void (*depr_print_clb)(NC_VERB_LEVEL level, const char *msg);
void (*print_clb)(const struct nc_session *session, NC_VERB_LEVEL level, const char *msg);

API void
nc_verbosity(NC_VERB_LEVEL level)
{
    ATOMIC_STORE_RELAXED(verbose_level, level);
    ly_log_level((LY_LOG_LEVEL)level);
}

struct {
    NC_VERB_LEVEL level;
    const char *label;
} verb[] = {
    {NC_VERB_ERROR, "[ERR]"},
    {NC_VERB_WARNING, "[WRN]"},
    {NC_VERB_VERBOSE, "[INF]"},
    {NC_VERB_DEBUG, "[DBG]"},
    {NC_VERB_DEBUG_LOWLVL, "[DBL]"}
};

#ifdef NC_ENABLED_SSH

API void
nc_libssh_thread_verbosity(int level)
{
    ssh_set_log_level(level);
}

#endif

static void
prv_vprintf(const struct nc_session *session, NC_VERB_LEVEL level, const char *format, va_list args)
{
#define PRV_MSG_INIT_SIZE 256
    va_list args2;
    char *prv_msg;
    void *mem;
    int req_len;

    prv_msg = malloc(PRV_MSG_INIT_SIZE);
    if (!prv_msg) {
        return;
    }

    va_copy(args2, args);

    req_len = vsnprintf(prv_msg, PRV_MSG_INIT_SIZE - 1, format, args);
    if (req_len == -1) {
        goto cleanup;
    } else if (req_len >= PRV_MSG_INIT_SIZE - 1) {
        /* the length is not enough */
        ++req_len;
        mem = realloc(prv_msg, req_len);
        if (!mem) {
            goto cleanup;
        }
        prv_msg = mem;

        /* now print the full message */
        req_len = vsnprintf(prv_msg, req_len, format, args2);
        if (req_len == -1) {
            goto cleanup;
        }
    }

    if (print_clb) {
        print_clb(session, level, prv_msg);
    } else if (depr_print_clb) {
        depr_print_clb(level, prv_msg);
    } else if (session && session->id) {
        fprintf(stderr, "Session %u %s: %s\n", session->id, verb[level].label, prv_msg);
    } else {
        fprintf(stderr, "%s: %s\n", verb[level].label, prv_msg);
    }

cleanup:
    free(prv_msg);
#undef PRV_MSG_INIT_SIZE
}

void
prv_printf(const struct nc_session *session, NC_VERB_LEVEL level, const char *format, ...)
{
    va_list ap;

    va_start(ap, format);
    prv_vprintf(session, level, format, ap);
    va_end(ap);
}

static void
nc_ly_log_clb(LY_LOG_LEVEL lvl, const char *msg, const char *UNUSED(path))
{
    if (print_clb) {
        print_clb(NULL, (NC_VERB_LEVEL)lvl, msg);
    } else if (depr_print_clb) {
        depr_print_clb((NC_VERB_LEVEL)lvl, msg);
    }
}

API void
nc_set_print_clb(void (*clb)(NC_VERB_LEVEL, const char *))
{
    print_clb = NULL;
    depr_print_clb = clb;
    ly_set_log_clb(nc_ly_log_clb, 1);
}

API void
nc_set_print_clb_session(void (*clb)(const struct nc_session *, NC_VERB_LEVEL, const char *))
{
    print_clb = clb;
    depr_print_clb = NULL;
    ly_set_log_clb(nc_ly_log_clb, 1);
}
