/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "python_private.h"  // must be first!

#include "qpid/dispatch/log.h"

#include "aprintf.h"
#include "entity.h"
#include "entity_cache.h"
#include "log_private.h"
#include "server_private.h"

#include "qpid/dispatch/alloc.h"
#include "qpid/dispatch/atomic.h"
#include "qpid/dispatch/ctools.h"
#include "qpid/dispatch/dispatch.h"
#include "qpid/dispatch/threading.h"

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

#define TEXT_MAX QD_LOG_TEXT_MAX
#define LOG_MAX (QD_LOG_TEXT_MAX+128)
#define LIST_MAX 1000

const char *QD_LOG_STATS_TYPE = "logStats";

static qd_log_source_t      *default_log_source=0;

int qd_log_max_len() { return TEXT_MAX; }

typedef struct qd_log_entry_t qd_log_entry_t;

struct qd_log_entry_t {
    DEQ_LINKS(qd_log_entry_t);
    char           *module;
    int             level;
    char           *file;
    int             line;
    struct timeval  time;
    char            text[TEXT_MAX];
};

ALLOC_DECLARE(qd_log_entry_t);
ALLOC_DEFINE(qd_log_entry_t);

DEQ_DECLARE(qd_log_entry_t, qd_log_list_t);
static qd_log_list_t         entries = {0};

static void qd_log_entry_free_lh(qd_log_entry_t* entry) {
    DEQ_REMOVE(entries, entry);
    free(entry->file);
    free(entry->module);
    free_qd_log_entry_t(entry);
}

// Ref-counted log sink, may be shared by several sources.
typedef struct log_sink_t {
    sys_atomic_t ref_count;
    char *name;
    bool syslog;
    FILE *file;
    DEQ_LINKS(struct log_sink_t);
} log_sink_t;

DEQ_DECLARE(log_sink_t, log_sink_list_t);

static log_sink_list_t sink_list = {0};

const char *format = "%Y-%m-%d %H:%M:%S.%%06lu %z";
bool utc = false;

void qd_log_global_options(const char* _format, bool _utc) {
    if (_format) format = _format;
    utc = _utc;
}


void qd_log_formatted_time(struct timeval *time, char *buf, size_t buflen)
{
    time_t sec = time->tv_sec;
    struct tm *tm_time = utc ? gmtime(&sec) : localtime(&sec);
    char fmt[100];
    strftime(fmt, sizeof fmt, format, tm_time);
    snprintf(buf, buflen, fmt, time->tv_usec);
}


static const char* SINK_STDOUT = "stdout";
static const char* SINK_STDERR = "stderr";
static const char* SINK_SYSLOG = "syslog";
static const char* SOURCE_DEFAULT = "DEFAULT";

static log_sink_t* find_log_sink_lh(const char* name) {
    log_sink_t* sink = DEQ_HEAD(sink_list);
    DEQ_FIND(sink, strcmp(sink->name, name) == 0);
    return sink;
}

// Must hold the log_source_lock
static void log_sink_free_lh(log_sink_t* sink) {
    if (!sink) return;
    assert(sink->ref_count);

    if (sys_atomic_dec(&sink->ref_count) == 1) {
        DEQ_REMOVE(sink_list, sink);
        free(sink->name);
        if (sink->file && sink->file != stderr)
            fclose(sink->file);
        if (sink->syslog)
            closelog();
        free(sink);
    }
}

static log_sink_t* log_sink_lh(const char* name) {
    log_sink_t* sink = find_log_sink_lh(name);
    if (sink) {
        sys_atomic_inc(&sink->ref_count);
    }
    else {
        bool syslog = false;
        FILE *file = 0;

        if (strcmp(name, SINK_STDERR) == 0) {
            file = stderr;
        }
        else if (strcmp(name, SINK_STDOUT) == 0) {
            file = stdout;
        }
        else if (strcmp(name, SINK_SYSLOG) == 0) {
            openlog(0, 0, LOG_DAEMON);
            syslog = true;
        }
        else {
            file = fopen(name, "a");
        }



        //If file is not there, return 0.
        // We are not logging an error here since we are already holding the log_source_lock
        // Writing a log message will try to re-obtain the log_source_lock lock and cause a deadlock.
        if (!file && !syslog) {
            return 0;
        }

        sink = NEW(log_sink_t);
        ZERO(sink);
        sys_atomic_init(&sink->ref_count, 1);
        sink->name = strdup(name);
        sink->syslog = syslog;
        sink->file = file;
        DEQ_INSERT_TAIL(sink_list, sink);

    }
    return sink;
}


typedef enum {DEFAULT, NONE, TRACE, DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, N_LEVELS} level_index_t;
#define MIN_VALID_LEVEL_INDEX TRACE
#define MAX_VALID_LEVEL_INDEX CRITICAL
#define N_LEVEL_INDICES (MAX_VALID_LEVEL_INDEX - MIN_VALID_LEVEL_INDEX + 1)
#define LEVEL_INDEX(LEVEL) ((LEVEL) - TRACE)

struct qd_log_source_t {
    DEQ_LINKS(qd_log_source_t);
    char *module;
    int mask;
    int includeTimestamp;       /* boolean or -1 means not set */
    int includeSource;          /* boolean or -1 means not set */
    bool syslog;
    log_sink_t *sink;
    uint64_t severity_histogram[N_LEVEL_INDICES];
};

DEQ_DECLARE(qd_log_source_t, qd_log_source_list_t);

static sys_mutex_t          *log_source_lock = 0;
static qd_log_source_list_t  source_list = {0};


typedef struct level_t {
    const char* name;
    int bit;     // QD_LOG bit
    int mask;    // Bit or higher
    const int syslog;
} level_t;

#define ALL_BITS (QD_LOG_CRITICAL | (QD_LOG_CRITICAL-1))

#define LEVEL(name, QD_LOG, SYSLOG) { name, QD_LOG,  ALL_BITS & ~(QD_LOG-1), SYSLOG }

static level_t levels[] = {
    {"default", -1, -1, 0},
    {"none", 0, 0, 0},
    LEVEL("trace",    QD_LOG_TRACE, LOG_DEBUG), /* syslog has no trace level */
    LEVEL("debug",    QD_LOG_DEBUG, LOG_DEBUG),
    LEVEL("info",     QD_LOG_INFO, LOG_INFO),
    LEVEL("notice",   QD_LOG_NOTICE, LOG_NOTICE),
    LEVEL("warning",  QD_LOG_WARNING, LOG_WARNING),
    LEVEL("error",    QD_LOG_ERROR, LOG_ERR),
    LEVEL("critical", QD_LOG_CRITICAL, LOG_CRIT)
};

static const level_t invalid_level = {"invalid", -2, -2, 0};

static char level_names[TEXT_MAX] = {0}; /* Set up in qd_log_initialize */

/// Return NULL and set qd_error if not a valid bit.
static const level_t* level_for_bit(int bit) {
    level_index_t i = 0;
    while (i < N_LEVELS && levels[i].bit != bit) ++i;
    if (i == N_LEVELS) {
        return &invalid_level;
    }
    return &levels[i];
}

/// Return NULL and set qd_error if not a valid level.
static const level_t* level_for_name(const char *name, int len) {
    level_index_t i = 0;
    while (i < N_LEVELS && strncasecmp(levels[i].name, name, len) != 0) ++i;
    if (i == N_LEVELS) {
        return &invalid_level;
    }
    return &levels[i];
}

/*
  Return -1 and set qd_error if not a valid bit.
  Translate so that the min valid level index is 0.
*/
static int level_index_for_bit(int bit) {
    level_index_t i = MIN_VALID_LEVEL_INDEX;
    while ( i <= MAX_VALID_LEVEL_INDEX ) {
        if ( levels[i].bit == bit )
            return (int) (i - MIN_VALID_LEVEL_INDEX);
        ++ i;
    }

    qd_error(QD_ERROR_CONFIG, "'%d' is not a valid log level bit.", bit);
    return -1;
}

/// Return the name of log level or 0 if not found.
static const char* level_name(int level) {
    return (0 <= level && level < N_LEVELS) ? levels[level].name : NULL;
}

static const char *SEPARATORS=", ;:";

/// Calculate the bit mask for a log enable string. Return -1 and set qd_error on error.
static int enable_mask(const char *enable_) {
    char *enable = qd_malloc(strlen(enable_) + 1);
    strcpy(enable, enable_);
    char *saveptr = 0;
    int mask = 0;
    for (const char *token = strtok_r(enable, SEPARATORS, &saveptr);
         token;
         token = strtok_r(NULL, SEPARATORS, &saveptr))
    {
        int len = strlen(token);
        int plus = (len > 0 && token[len-1] == '+') ? 1 : 0;
        const level_t* level = level_for_name(token, len-plus);
        mask |= (plus ? level->mask : level->bit);
    }
    free(enable);
    return mask;
}

/// Caller must hold log_source_lock
static qd_log_source_t* lookup_log_source_lh(const char *module)
{
    if (strcasecmp(module, SOURCE_DEFAULT) == 0)
        return default_log_source;
    qd_log_source_t *src = DEQ_HEAD(source_list);
    DEQ_FIND(src, strcasecmp(module, src->module) == 0);
    return src;
}

static bool default_bool(int value, int default_value) {
    return value == -1 ? default_value : value;
}

static void write_log(qd_log_source_t *log_source, qd_log_entry_t *entry)
{
    log_sink_t* sink = log_source->sink ? log_source->sink : default_log_source->sink;
    if (!sink) return;

    char log_str[LOG_MAX];
    char *begin = log_str;
    char *end = log_str + LOG_MAX;

    const level_t *level = level_for_bit(entry->level);
    if (level->bit == -2) {
        level = &levels[INFO];
        qd_error_clear();
    }

    if (default_bool(log_source->includeTimestamp, default_log_source->includeTimestamp)) {
        char buf[100];
        buf[0] = '\0';

        qd_log_formatted_time(&entry->time, buf, 100);

        aprintf(&begin, end, "%s ", buf);
    }

    aprintf(&begin, end, "%s (%s) %s", entry->module, level->name, entry->text);

    if (default_bool(log_source->includeSource, default_log_source->includeSource) && entry->file)
        aprintf(&begin, end, " (%s:%d)", entry->file, entry->line);

    aprintf(&begin, end, "\n");

    if (sink->file) {
        if (fputs(log_str, sink->file) == EOF) {
            char msg[TEXT_MAX];
            snprintf(msg, sizeof(msg), "Cannot write log output to '%s'", sink->name);
            perror(msg);
            exit(1);
        };
        fflush(sink->file);
    }
    if (sink->syslog) {
        int syslog_level = level->syslog;
        if (syslog_level != -1)
            syslog(syslog_level, "%s", log_str);
    }
}

/// Reset the log source to the default state
static void qd_log_source_defaults(qd_log_source_t *log_source) {
    log_source->mask = -1;
    log_source->includeTimestamp = -1;
    log_source->includeSource = -1;
    log_source->sink = 0;
    memset ( log_source->severity_histogram, 0, sizeof(uint64_t) * (N_LEVEL_INDICES) );
}

/// Caller must hold the log_source_lock
static qd_log_source_t *qd_log_source_lh(const char *module)
{
    qd_log_source_t *log_source = lookup_log_source_lh(module);
    if (!log_source)
    {
        log_source = NEW(qd_log_source_t);
        ZERO(log_source);
        log_source->module = (char*) malloc(strlen(module) + 1);
        strcpy(log_source->module, module);
        qd_log_source_defaults(log_source);
        DEQ_INSERT_TAIL(source_list, log_source);
        qd_entity_cache_add(QD_LOG_STATS_TYPE, log_source);
    }
    return log_source;
}

qd_log_source_t *qd_log_source(const char *module)
{
    sys_mutex_lock(log_source_lock);
    qd_log_source_t* src = qd_log_source_lh(module);
    sys_mutex_unlock(log_source_lock);
    return src;
}

qd_log_source_t *qd_log_source_reset(const char *module)
{
    sys_mutex_lock(log_source_lock);
    qd_log_source_t* src = qd_log_source_lh(module);
    qd_log_source_defaults(src);
    sys_mutex_unlock(log_source_lock);
    return src;
}

static void qd_log_source_free_lh(qd_log_source_t* src) {
    DEQ_REMOVE(source_list, src);
    log_sink_free_lh(src->sink);
    free(src->module);
    free(src);
}

bool qd_log_enabled(qd_log_source_t *source, qd_log_level_t level) {
    if (!source) return false;
    int mask = source->mask == -1 ? default_log_source->mask : source->mask;
    return level & mask;
}

void qd_vlog_impl(qd_log_source_t *source, qd_log_level_t level, bool check_level, const char *file, int line, const char *fmt, va_list ap)
{
    /*-----------------------------------------------
      Count this log-event in this log's histogram
      whether or not this log is currently enabled.
      We can always decide not to look at it later,
      based on its used/unused status.
    -----------------------------------------------*/
    int level_index = level_index_for_bit(level);
    if (level_index < 0)
        qd_error_clear();
    else
        source->severity_histogram[level_index]++;

    if (check_level) {
        if (!qd_log_enabled(source, level))
            return;
    }

    // Bounded buffer of log entries, keep most recent.
    qd_log_entry_t *entry = new_qd_log_entry_t();
    DEQ_ITEM_INIT(entry);

    //
    // Obtain the log_source_lock global lock. We need to do this, if not, the qd_log_entity() function
    // could free the log_source->sink from underneath you and replace it with a new sink.
    // Once we obtain this lock, we only release the lock once the log line is written to the sink.
    //
    sys_mutex_lock(log_source_lock);
    entry->module = source->module ? strdup(source->module) : 0;
    entry->level  = level;
    entry->file   = file ? strdup(file) : 0;
    entry->line   = line;
    gettimeofday(&entry->time, NULL);
    vsnprintf(entry->text, TEXT_MAX, fmt, ap);
    write_log(source, entry);
    DEQ_INSERT_TAIL(entries, entry);
    if (DEQ_SIZE(entries) > LIST_MAX)
        qd_log_entry_free_lh(DEQ_HEAD(entries));
    sys_mutex_unlock(log_source_lock);
}

void qd_log_impl_v1(qd_log_source_t *source, qd_log_level_t level,  const char *file, int line, const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    qd_vlog_impl(source, level, false, file, line, fmt, ap);
    va_end(ap);
}

void qd_log_impl(qd_log_source_t *source, qd_log_level_t level, const char *file, int line, const char *fmt, ...)
{
  va_list ap;
  va_start(ap, fmt);
  qd_vlog_impl(source, level, true, file, line, fmt, ap);
  va_end(ap);
}

static PyObject *inc_none() { Py_INCREF(Py_None); return Py_None; }

/// Return the log buffer up to limit as a python list. Called by management agent.
QD_EXPORT PyObject *qd_log_recent_py(long limit) {
    if (PyErr_Occurred()) return NULL;
    PyObject *list = PyList_New(0);
    PyObject *py_entry = NULL;
    if (!list) goto error;
    qd_log_entry_t *entry = DEQ_TAIL(entries);
    while (entry && limit) {
        const int ENTRY_SIZE=6;
        py_entry = PyList_New(ENTRY_SIZE);
        if (!py_entry) goto error;
        int i = 0;
        // NOTE: PyList_SetItem steals a reference so no leak here.
        PyList_SetItem(py_entry, i++, PyUnicode_FromString(entry->module));
        const char* level = level_name( level_index_for_bit(entry->level) + 2 );
        PyList_SetItem(py_entry, i++, level ? PyUnicode_FromString(level) : inc_none());
        PyList_SetItem(py_entry, i++, PyUnicode_FromString(entry->text));
        PyList_SetItem(py_entry, i++, entry->file ? PyUnicode_FromString(entry->file) : inc_none());
        PyList_SetItem(py_entry, i++, entry->file ? PyLong_FromLong(entry->line) : inc_none());
        PyList_SetItem(py_entry, i++, PyLong_FromLongLong((PY_LONG_LONG)entry->time.tv_sec));
        assert(i == ENTRY_SIZE);
        if (PyErr_Occurred()) goto error;
        PyList_Insert(list, 0, py_entry);
        Py_DECREF(py_entry);
        if (limit > 0) --limit;
        entry = DEQ_PREV(entry);
    }
    return list;
 error:
    Py_XDECREF(list);
    Py_XDECREF(py_entry);
    return NULL;
}

void qd_log_initialize(void)
{
    DEQ_INIT(entries);
    DEQ_INIT(source_list);
    DEQ_INIT(sink_list);

    // Set up level_names for use in error messages.
    char *begin = level_names, *end = level_names+sizeof(level_names);
    aprintf(&begin, end, "%s", levels[NONE].name);
    for (level_index_t i = NONE + 1; i < N_LEVELS; ++i)
        aprintf(&begin, end, ", %s", levels[i].name);

    log_source_lock = sys_mutex();

    default_log_source = qd_log_source(SOURCE_DEFAULT);
    default_log_source->mask = levels[INFO].mask;
    default_log_source->includeTimestamp = true;
    default_log_source->includeSource = 0;
    default_log_source->sink = log_sink_lh(SINK_STDERR);
}


void qd_log_finalize(void) {
    while (DEQ_HEAD(source_list))
        qd_log_source_free_lh(DEQ_HEAD(source_list));
    while (DEQ_HEAD(entries))
        qd_log_entry_free_lh(DEQ_HEAD(entries));
    while (DEQ_HEAD(sink_list))
        log_sink_free_lh(DEQ_HEAD(sink_list));
    default_log_source = NULL;  // stale value would misconfigure new router started again in the same process
}

QD_EXPORT qd_error_t qd_log_entity(qd_entity_t *entity)
{
    qd_error_clear();

    char* module = 0;
    char *outputFile = 0;
    char *enable = 0;
    int include_timestamp = 0;
    int include_source = 0;

    bool has_enable = false;
    bool has_output_file = false;
    bool has_include_timestamp = false;
    bool has_include_source = false;
    bool is_sink_syslog = false;
    bool trace_enabled = false;
    bool error_in_output = false;
    bool error_in_enable = false;

    do {
        //
        // A module attribute MUST be specified for a log entity.
        // Every other attribute is optional.
        //
        module = qd_entity_get_string(entity, "module");

        //
        // If the module is not specified, there is nothing to do, just log an
        // error and break out of this do loop.
        //
        QD_ERROR_BREAK();

        //
        // Obtain all attributes from the entity before obtaining the log_source_lock.
        // We do this because functions like qd_entity_get_string and qd_entity_get_bool ultimately call qd_vlog_impl() which
        // also holds the log_source_lock when calling write_log().
        //

        if (qd_entity_has(entity, "outputFile")) {
            has_output_file = true;
            outputFile = qd_entity_get_string(entity, "outputFile");
            QD_ERROR_BREAK();
        }

        if (qd_entity_has(entity, "enable")) {
            has_enable = true;
            enable = qd_entity_get_string(entity, "enable");
            QD_ERROR_BREAK();
        }

        if (qd_entity_has(entity, "includeTimestamp")) {
            has_include_timestamp = true;
            include_timestamp = qd_entity_get_bool(entity, "includeTimestamp");
            QD_ERROR_BREAK();
        }

        if (qd_entity_has(entity, "includeSource")) {
            has_include_source = true;
            include_source = qd_entity_get_bool(entity, "includeSource");
            QD_ERROR_BREAK();
        }

        //
        // Obtain the log_source_lock lock. This lock is also used when write_log() is called.
        //
        sys_mutex_lock(log_source_lock);

        qd_log_source_t *src = qd_log_source_lh(module); /* The original(already existing) log source */

        if (has_output_file) {
            log_sink_t* sink = log_sink_lh(outputFile);
            if (!sink) {
                error_in_output = true;
                sys_mutex_unlock(log_source_lock);
                break;
            }

            // DEFAULT source may already have a sink, so free the old sink first
            if (src->sink) {
                log_sink_free_lh(src->sink);
            }

            // Assign the new sink
            src->sink = sink;

            if (src->sink->syslog) {
                // Timestamp should be off for syslog.
                is_sink_syslog = true;
                src->includeTimestamp = 0;
            }
        }

        if (has_enable) {
            int mask = enable_mask(enable);

            if (mask < -1) {
                error_in_enable = true;
                sys_mutex_unlock(log_source_lock);
                break;
            }
            else {
                src->mask = mask;
            }

            if (qd_log_enabled(src, QD_LOG_TRACE)) {
                trace_enabled = true;
            }
        }

        if (has_include_timestamp && !is_sink_syslog) {
            // Timestamp should be off for syslog.
            src->includeTimestamp = include_timestamp;
        }

        if (has_include_source) {
            src->includeSource = include_source;
        }

        sys_mutex_unlock(log_source_lock);

    } while(0);

    if (error_in_output) {
        char msg[TEXT_MAX];
        snprintf(msg, sizeof(msg), "Failed to open log file '%s'", outputFile);
        qd_error(QD_ERROR_CONFIG, "%s", msg);
    }
    if (error_in_enable) {
        qd_error(QD_ERROR_CONFIG, "'%s' is not a valid log level. Should be one of {%s}.",  enable, level_names);
    }

    if (module)
        free(module);
    if (outputFile)
        free(outputFile);
    if (enable)
        free(enable);

    //
    // If trace logging is enabled, loop thru all connections in the router and call the pn_transport_set_tracer callback
    // so proton frame trace can be output as part of the router trace log.
    //
    if (trace_enabled) {
        qd_server_trace_all_connections();
    }

    return qd_error_code();
}

void qd_format_string(char* buf, int buf_size, const char *fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    vsnprintf(buf, buf_size, fmt, args);
    va_end(args);
}

QD_EXPORT qd_error_t qd_entity_refresh_logStats(qd_entity_t* entity, void *impl)
{
    qd_log_source_t *log = (qd_log_source_t*)impl;
    char identity_str[TEXT_MAX];
    snprintf(identity_str, TEXT_MAX - 1,"logStats/%s", log->module);

    qd_entity_set_long(entity,   "traceCount",    log->severity_histogram[LEVEL_INDEX(TRACE)]);
    qd_entity_set_long(entity,   "debugCount",    log->severity_histogram[LEVEL_INDEX(DEBUG)]);
    qd_entity_set_long(entity,   "infoCount",     log->severity_histogram[LEVEL_INDEX(INFO)]);
    qd_entity_set_long(entity,   "noticeCount",   log->severity_histogram[LEVEL_INDEX(NOTICE)]);
    qd_entity_set_long(entity,   "warningCount",  log->severity_histogram[LEVEL_INDEX(WARNING)]);
    qd_entity_set_long(entity,   "errorCount",    log->severity_histogram[LEVEL_INDEX(ERROR)]);
    qd_entity_set_long(entity,   "criticalCount", log->severity_histogram[LEVEL_INDEX(CRITICAL)]);
    qd_entity_set_string(entity, "name",          log->module);
    qd_entity_set_string(entity, "identity",      identity_str);

    return QD_ERROR_NONE;
}
