/*
<:copyright-BRCM:2016:DUAL/GPL:standard

   Broadcom Proprietary and Confidential.(c) 2016 Broadcom
   All Rights Reserved

Unless you and Broadcom execute a separate written software license
agreement governing use of this software, this software is licensed
to you under the terms of the GNU General Public License version 2
(the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
with the following added to such license:

   As a special exception, the copyright holders of this software give
   you permission to link this software with independent modules, and
   to copy and distribute the resulting executable under terms of your
   choice, provided that you also meet, for each linked independent
   module, the terms and conditions of the license of that module.
   An independent module is a module which is not derived from this
   software.  The special exception does not apply to any modifications
   of the software.

Not withstanding the above, under no circumstances may you combine
this software in any way with any other Broadcom software provided
under a license other than the GPL, without Broadcom's express prior
written consent.

:>
 */

#ifdef ENABLE_LOG

#include "bcm_dev_log_task.h"
#include "bcm_dev_log_task_internal.h"
#include "bcm_dev_log.h"

static bcmos_timer dev_log_timer;

/* Store timestamp per every rate-limited log ID. */
static uint64_t rate_limit_id2timestamp[DEV_LOG_RATE_LIMIT_ID__NUM_OF];

const char *dev_log_basename(const char *str)
{
    const char *slash;
    if ((slash = strchr(str, '/')))
    {
        const char *str0 = str;
        str = strchr(slash+1, ' ');
        /* If log format string was created by BCM_LOG macro and there is no corruption of some kind
         * str above is guaranteed to be != NULL. However, making str!=NULL assumption makes dev_log
         * vulnerable to bugs in the caller. In this case the following inexpensive check prevents crash
         * in dev_Log and helps in identifying the real culprit.
         */
        if (!str)
            return str0;
        while (str[0] != '/')
            str--;
        str++;
    }
    return str;
}

#ifdef TRIGGER_LOGGER_FEATURE

/* check if the message fits the level and the other criteria for a trigger
   return 1 if yes, the message will be printed
   and returns 0 if the message will not be printed
*/
static bcmos_bool check_trigger(dev_log_id_parm *xi_id, bcm_dev_log_level xi_log_level)
{
    /* the level of the message must be exactly the trigger level */
    if (xi_id->trigger_log_level != xi_log_level)
        return BCMOS_FALSE; /* do not print the message  - the level does not fit */
    
    xi_id->trigger.counter++;
    if (xi_id->trigger.counter >= xi_id->trigger.start_threshold)
    {
        if (xi_id->trigger.counter >= xi_id->trigger.stop_threshold)
        {
            /* trigger finished, check repeat */
            if (xi_id->trigger.repeat_threshold)
            {
                xi_id->trigger.repeat++;
                if (xi_id->trigger.repeat < xi_id->trigger.repeat_threshold)
                {
                    /* rewind trigger conditions */
                    xi_id->trigger.counter = 0;
                }
            }
        }
        else /* trigger is active : counter greater than start and less than end */
            return BCMOS_TRUE; /* print the message */
    }
    return BCMOS_FALSE;/* do not print the message  - still less than start threshold */
}

/* check if the message fits the level and the criteria for throttle
   return 1 if yes, the message will be printed
   and returns 0 if the message will not be printed
*/
static bcmos_bool check_throttle(dev_log_id_parm *xi_id, bcm_dev_log_level xi_log_level)
{
    /* check if any throttle is defined */
    if (xi_id->throttle_log_level != DEV_LOG_LEVEL_NO_LOG)
        return BCMOS_TRUE; /* print the message  - no trigger is set */
    
    /* the level of the message must be exactly the throttle level */
    if (xi_id->throttle_log_level != xi_log_level)
        return BCMOS_FALSE; /* do not print the message  - the level does not fit */
    
    xi_id->throttle.counter++;
    if (xi_id->throttle.counter >= xi_id->throttle.threshold)
    {
        xi_id->throttle.counter = 0;
        return BCMOS_TRUE;
    }
    return BCMOS_FALSE;/* do not print the message  - still less than start threshold */
}

#endif

static bcmos_timer_rc bcm_dev_log_msg_send_timer_cb(bcmos_timer *timer, long data)
{
    bcmos_msg *msg = (bcmos_msg *)data;
    bcmos_msg_send(&dev_log.save_queue, msg, BCMOS_MSG_SEND_AUTO_FREE);
    return BCMOS_TIMER_OK;
}

uint8_t bcm_dev_log_pool_occupancy_percent_get(void)
{
    bcmos_msg_pool_info msg_pool_info;
    bcmos_errno error = bcmos_msg_pool_query(&dev_log.pool, &msg_pool_info);
    if (error != BCM_ERR_OK)
    {
        DEV_LOG_ERROR_PRINTF("bcmos_msg_pool_query() returned %s (%d)\n", bcmos_strerror(error), error);
        return 0;
    }
    return (uint8_t)((100 * (msg_pool_info.parm.size - msg_pool_info.stat.free)) / msg_pool_info.parm.size);
}

static bcmos_bool bcm_dev_log_should_drop(
    dev_log_id_parm *id,
    bcm_dev_log_level log_level,
    uint32_t rate_us,
    dev_log_rate_limit_id rate_limit_id)
{
    /* If the msg pool is sufficiently full, drop all non-error messages */
    if (!bcm_dev_log_level_is_error(log_level) &&
        bcm_dev_log_pool_occupancy_percent_get() >= DEV_LOG_ERROR_ONLY_THRESHOLD_PERCENT)
    {
        bcm_dev_log_drop_report();
        return BCMOS_TRUE;
    }
    
#ifdef TRIGGER_LOGGER_FEATURE
    /* if trigger defined - ignore throttle and printing level */
    if (id->trigger_log_level != DEV_LOG_LEVEL_NO_LOG)
        return check_trigger(id, log_level);
#endif
    
    /* if trigger is not fullfilled - check other conditions */
    if (log_level > id->log_level_print && log_level > id->log_level_save)
        return BCMOS_TRUE;
    
#ifdef TRIGGER_LOGGER_FEATURE
    if (!check_throttle(id, log_level))
        return BCMOS_TRUE;
#endif

    if (rate_us && rate_limit_id != DEV_LOG_RATE_LIMIT_ID_NONE)
    {
        uint64_t curr_timestamp;

        /* Do rate limit. */
        curr_timestamp = bcmos_timestamp64();
        if (curr_timestamp - rate_limit_id2timestamp[rate_limit_id] < rate_us)
            return BCMOS_TRUE; /* Filter out this message. */
        rate_limit_id2timestamp[rate_limit_id] = curr_timestamp;
    }

    return BCMOS_FALSE;
}

static void _bcm_dev_log_vlog(dev_log_id xi_id,
    bcm_dev_log_level xi_log_level,
    uint32_t xi_flags,
    uint32_t rate_us,
    dev_log_rate_limit_id rate_limit_id, 
    const char *fmt,
    va_list args)
{
    dev_log_id_parm *id = (dev_log_id_parm *)xi_id;
    dev_log_queue_msg *log_queue_msg;
    bcmos_errno error = BCM_ERR_OK;
    bcmos_msg *msg;

    if (dev_log.state != BCM_DEV_LOG_STATE_ENABLED)
    {
        if (dev_log.flags & BCM_DEV_LOG_FLAG_DISABLED_WITH_PRINTF)
            DEV_LOG_VPRINTF(fmt, args);
        return;
    }
    if (!xi_id || (xi_id == DEV_LOG_INVALID_ID))
    {
        /* If this ID was not registered - or registered incorrectly */
        DEV_LOG_ERROR_PRINTF("Error: xi_id not valid (0x%x)\n", (unsigned int)xi_id);
        DEV_LOG_VPRINTF(fmt, args); /* This will allow us to debug what line caused the bug. */
        return;
    }
    if ((xi_log_level >= DEV_LOG_LEVEL_NUM_OF) || (xi_log_level == DEV_LOG_LEVEL_NO_LOG))
    {
        DEV_LOG_ERROR_PRINTF("xi_log_level (%u) is invalid\n", xi_log_level);
        DEV_LOG_VPRINTF(fmt, args); /* This will allow us to debug what line caused the bug. */
        return;
    }
    if (id->log_type == DEV_LOG_ID_TYPE_NONE)
    {
        return;
    }
#ifdef BCM_SUBSYSTEM_HOST
    /* Always use CALLER_FMT mode on the host to avoid portability issues with
     * transferring va_list as an array */
    xi_flags |= BCM_LOG_FLAG_CALLER_FMT;
#endif

    /* Update log id counters  */
    id->counters[xi_log_level]++;

    if (bcm_dev_log_should_drop(id, xi_log_level, rate_us, rate_limit_id))
        return;

    msg = bcmos_msg_pool_alloc(&dev_log.pool);
    if (!msg)
    {
        bcm_dev_log_drop_report();
        return;
    }
    log_queue_msg = msg->data;
    /* Create log message */
    log_queue_msg->log_id = id;
    log_queue_msg->time_stamp = dev_log.dev_log_parm.get_time_cb();
    log_queue_msg->msg_level = xi_log_level;
    log_queue_msg->flags = xi_flags;
#ifndef BCM_SUBSYSTEM_HOST
    /* It is not really necessary to compile out non CALLER_FMT case on the host.
     * However, keeping unused code will make Coverity unhappy */
    if (unlikely(xi_flags & BCM_LOG_FLAG_CALLER_FMT))
    {
#endif /* #ifndef BCM_SUBSYSTEM_HOST */
        vsnprintf(log_queue_msg->u.str, MAX_DEV_LOG_STRING_SIZE, (xi_flags & BCM_LOG_FLAG_FILENAME_IN_FMT) ? dev_log_basename(fmt) : fmt, args);
#ifndef BCM_SUBSYSTEM_HOST
    }
    else
    {
        uint32_t i;
        uint32_t offset;
        log_queue_msg->u.fmt_args.fmt = fmt;

        offset = ((long)log_queue_msg->u.fmt_args.args % 8 == 0) ? 0 : 1; /* start on an 8-byte boundary */
        for (i = 0; i < DEV_LOG_MAX_ARGS; i++)
        {
            log_queue_msg->u.fmt_args.args[i + offset] = va_arg(args, void *);
        }
    }
#endif /* #ifndef BCM_SUBSYSTEM_HOST */

    if (bcmos_sem_post_is_allowed())
    {
        error = bcmos_msg_send(&dev_log.save_queue, msg, BCMOS_MSG_SEND_AUTO_FREE);
    }
    else
    {
        bcmos_timer_parm timer_params =
        {
            .name = "dev_log_timer",
            .handler = bcm_dev_log_msg_send_timer_cb,
        };

        if (!(dev_log_timer.flags & BCMOS_TIMER_FLAG_VALID))
            bcmos_timer_create(&dev_log_timer, &timer_params);
        /* Limitation: We don't send more than 1 logger message even if _bcm_dev_log_vlog() was called multiple timers in IRQs disabled mode because we have a single timer. */
        if (!bcmos_timer_is_running(&dev_log_timer))
        {
            bcmos_timer_handler_set(&dev_log_timer, bcm_dev_log_msg_send_timer_cb, (long)msg);
            bcmos_timer_start(&dev_log_timer, 0);
        }
    }

    if (error != BCM_ERR_OK)
    {
        id->lost_msg_cnt++;
    }
}

void bcm_dev_log_vlog(dev_log_id xi_id,
    bcm_dev_log_level xi_log_level,
    uint32_t xi_flags,
    const char *fmt,
    va_list args)
{
    _bcm_dev_log_vlog(xi_id, xi_log_level, xi_flags, 0, DEV_LOG_RATE_LIMIT_ID_NONE, fmt, args);
}

/* IMPORTANT!!!
 * The function bcm_dev_log_log() must have even number of arguments before the '...' (see comments on header file).
 */
void bcm_dev_log_log(dev_log_id xi_id,
    bcm_dev_log_level xi_log_level,
    uint32_t xi_flags,
    const char *fmt,
    ...)
{
    va_list args;

    va_start(args, fmt);
    bcm_dev_log_vlog(xi_id, xi_log_level, xi_flags, fmt, args);
    va_end(args);
}

void bcm_dev_log_log_ratelimit(dev_log_id xi_id,
    bcm_dev_log_level xi_log_level,
    uint32_t xi_flags,
    uint32_t rate_us,
    dev_log_rate_limit_id rate_limit_id,
    const char *fmt,
    ...)
{
    va_list args;

    va_start(args, fmt);
    _bcm_dev_log_vlog(xi_id, xi_log_level, xi_flags, rate_us, rate_limit_id, fmt, args);
    va_end(args);
}

#ifdef BCMOS_TRACE_IN_DEV_LOG

static dev_log_id bcmos_trace_dev_log_id[] =
{
    [BCMOS_TRACE_LEVEL_NONE] = DEV_LOG_INVALID_ID,
    [BCMOS_TRACE_LEVEL_ERROR] = DEV_LOG_INVALID_ID,
    [BCMOS_TRACE_LEVEL_INFO] = DEV_LOG_INVALID_ID,
    [BCMOS_TRACE_LEVEL_VERBOSE] = DEV_LOG_INVALID_ID,
    [BCMOS_TRACE_LEVEL_DEBUG] = DEV_LOG_INVALID_ID
};

static bcm_dev_log_level bcmos_trace_dev_log_level[] =
{
    [BCMOS_TRACE_LEVEL_ERROR] = DEV_LOG_LEVEL_ERROR,
    [BCMOS_TRACE_LEVEL_INFO] = DEV_LOG_LEVEL_INFO,
    [BCMOS_TRACE_LEVEL_VERBOSE] = DEV_LOG_LEVEL_INFO,
    [BCMOS_TRACE_LEVEL_DEBUG] = DEV_LOG_LEVEL_DEBUG
};

#endif

/********************************************************************************************/
/*                                                                                          */
/* Name: bcm_dev_log_os_trace_init                                                          */
/*                                                                                          */
/* Abstract: Direct bcmos_trace() output to log                                             */
/* Arguments: NONE                                                                          */
/*                                                                                          */
/* Return Value:                                                                            */
/*   bcmos_errno - Success code (BCM_ERR_OK) or Error code (see bcmos_errno.h)              */
/*                                                                                          */
/********************************************************************************************/
bcmos_errno bcm_dev_log_os_trace_init(void)
{
#ifdef BCMOS_TRACE_IN_DEV_LOG
    bcmos_trace_dev_log_id[BCMOS_TRACE_LEVEL_ERROR] = bcm_dev_log_id_register("trace_error",
        DEV_LOG_LEVEL_ERROR, DEV_LOG_ID_TYPE_BOTH);
    bcmos_trace_dev_log_id[BCMOS_TRACE_LEVEL_INFO] = bcm_dev_log_id_register("trace_info",
        DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
    bcmos_trace_dev_log_id[BCMOS_TRACE_LEVEL_VERBOSE] = bcmos_trace_dev_log_id[BCMOS_TRACE_LEVEL_INFO];
    bcmos_trace_dev_log_id[BCMOS_TRACE_LEVEL_DEBUG] = bcm_dev_log_id_register("trace_debug",
        DEV_LOG_LEVEL_DEBUG, DEV_LOG_ID_TYPE_BOTH);
    if (bcmos_trace_dev_log_id[BCMOS_TRACE_LEVEL_ERROR] == DEV_LOG_INVALID_ID ||
        bcmos_trace_dev_log_id[BCMOS_TRACE_LEVEL_INFO]  == DEV_LOG_INVALID_ID ||
        bcmos_trace_dev_log_id[BCMOS_TRACE_LEVEL_DEBUG] == DEV_LOG_INVALID_ID)
    {
        return BCM_ERR_NORES;
    }
    return BCM_ERR_OK;
#else /* #ifdef BCMOS_TRACE_IN_DEV_LOG */
    return BCM_ERR_NOT_SUPPORTED;
#endif
}

#ifdef BCMOS_TRACE_IN_DEV_LOG

/* Direct OS trace to dev_log */
void bcmos_trace(bcmos_trace_level level, const char *format, ...)
{
    va_list args;

    va_start(args, format);
    if (bcmos_trace_dev_log_id[level] != DEV_LOG_INVALID_ID && dev_log.state == BCM_DEV_LOG_STATE_ENABLED)
    {
        if (level == BCMOS_TRACE_LEVEL_ERROR)
            bcm_dev_log_vlog(bcmos_trace_dev_log_id[level], bcmos_trace_dev_log_level[level], BCM_LOG_FLAG_CALLER_FMT, format, args);
        else
            bcm_dev_log_vlog(bcmos_trace_dev_log_id[level], bcmos_trace_dev_log_level[level], 0, format, args);
    }

    va_end(args);
}

#endif

#endif /* ENABLE_LOG */
