/*
<: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.

:>
 */

#include <bcmos_system.h>
#include <bcmolt_msg.h>
#include <bcm_dev_log.h>
#include <bcm_api_cli_helpers.h>
#include "bcm_api_dev_log.h"

/* maximum number of tasks that can use the API/logger integration simultaneously */
#define API_LOG_NUM_BLKS 16

/* string that denotes that this entry is not complete - there is more data to come */
#define API_LOG_CONT_STR "..."

/* number of characters reserved at the end of each log entry (continuation string + newline) */
#define API_LOG_ENTRY_OVERHEAD sizeof(API_LOG_CONT_STR)

typedef struct
{
    dev_log_id log_id;
    const bcmolt_msg *msg;
    char *buf;
    uint32_t used;
} api_log_rec;

static bcmos_blk_pool api_log_blk_pool;

static bcmos_errno api_log_dump_data_type(
    api_log_rec *rec,
    const bcmcli_type_descr *td,
    const void *data,
    const char *name,
    uint32_t num_entries,
    uint32_t entry_size);

static bcmos_bool api_log_is_singleton(bcmolt_mgt_group group)
{
    switch (group)
    {
    case BCMOLT_MGT_GROUP_CFG:
    case BCMOLT_MGT_GROUP_STAT:
    case BCMOLT_MGT_GROUP_STAT_CFG:
    case BCMOLT_MGT_GROUP_AUTO_CFG:
        return BCMOS_TRUE;
    default:
        return BCMOS_FALSE;
    }
}

static inline uint32_t api_log_buf_remaining(const api_log_rec *rec)
{
    return (MAX_DEV_LOG_STRING_NET_SIZE - API_LOG_ENTRY_OVERHEAD) - rec->used;
}

static void api_log_flush(api_log_rec *rec, const char *end_of_line)
{
    if (rec->used != 0)
    {
        strncat(rec->buf, end_of_line, MAX_DEV_LOG_STRING_NET_SIZE - rec->used);
        bcm_dev_log_log(rec->log_id, DEV_LOG_LEVEL_INFO, BCM_LOG_FLAG_CALLER_FMT, "%s", rec->buf);
        rec->used = 0;
    }
}

static void api_log_print(api_log_rec *rec, const char *format, ...)
{
    va_list args;
    int ret;

    va_start(args, format);
    ret = vsnprintf(rec->buf + rec->used, api_log_buf_remaining(rec), format, args);
    va_end(args);

    if (ret < 0 || ret > api_log_buf_remaining(rec))
    {
        /* this print doesn't fit in the buffer - send the current buffer and create a new continuation log entry */
        rec->buf[rec->used] = '\0';
        api_log_flush(rec, API_LOG_CONT_STR "\n");

        /* the continuation entry can skip the header */
        api_log_print(rec, API_LOG_CONT_STR);

        /* try again, this time against the continuation entry */
        va_start(args, format);
        ret = vsnprintf(rec->buf + rec->used, api_log_buf_remaining(rec), format, args);
        va_end(args);

        if (ret < 0 || ret > api_log_buf_remaining(rec))
        {
            BCM_LOG(ERROR, rec->log_id, "API message log overflow on msg #%u\n", rec->msg->corr_tag);
        }
        else
        {
            rec->used += ret;
        }
    }
    else
    {
        rec->used += ret;
    }
}

static bcmos_errno api_log_read_snum(const bcmcli_type_descr *td, const void *data, int64_t *n)
{
    switch (td->size)
    {
    case 1:
    {
        int8_t n1 = *(const int8_t *)data;
        *n = n1;
        break;
    }
    case 2:
    {
        int16_t n2 = *(const int16_t *)data;
        *n = n2;
        break;
    }
    case 4:
    {
        int32_t n4 = *(const int32_t *)data;
        *n = n4;
        break;
    }
    case 8:
    {
        memcpy(n, data, sizeof(*n));
        break;
    }
    default:
        return BCM_ERR_NOT_SUPPORTED;
    }
    return BCM_ERR_OK;
}

static bcmos_errno api_log_read_unum(const bcmcli_type_descr *td, const void *data, uint64_t *n)
{
    switch (td->size)
    {
    case 1:
    {
        uint8_t n1 = *(const uint8_t *)data;
        *n = n1;
        break;
    }
    case 2:
    {
        uint16_t n2 = *(const uint16_t *)data;
        *n = n2;
        break;
    }
    case 4:
    {
        uint32_t n4 = *(const uint32_t *)data;
        *n = n4;
        break;
    }
    case 8:
    {
        memcpy(n, data, sizeof(*n));
        break;
    }
    default:
        return BCM_ERR_NOT_SUPPORTED;
    }
    return BCM_ERR_OK;
}

/* break a string up into smaller chunks (preferably at \n boundaries) so we don't overflow the size of a log entry */
static void api_log_print_long_line(api_log_rec *rec, const char *line, uint32_t len)
{
    uint32_t i;
    uint32_t handled = 0;
    for (i = 0; i < len; i++)
    {
        if (line[i] == '\n')
        {
            if (i > handled)
            {
                api_log_print(rec, "%.*s", i - handled, &line[handled]);
                api_log_flush(rec, API_LOG_CONT_STR "\n");
                api_log_print(rec, API_LOG_CONT_STR);
            }
            handled = i + 1;
        }
        if (i > handled && i - handled == 32)
        {
            api_log_print(rec, "%.*s", 32, &line[handled]);
            handled = i;
        }
    }
    if (handled < len)
    {
        api_log_print(rec, "%.*s", len - handled, &line[handled]);
    }
}

static bcmos_errno api_log_dump_simple_data_type(
    api_log_rec *rec,
    const bcmcli_type_descr *td,
    const void *data,
    const char *name)
{
    bcmos_errno err = BCM_ERR_OK;

    switch (td->base_type)
    {
    case BCMOLT_BASE_TYPE_ID_SNUM:       /* signed number */
    {
        int64_t n = 0;
        err = api_log_read_snum(td, data, &n);
        api_log_print(rec, "%lld", (long long)n);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_UNUM:       /* unsigned number */
    {
        uint64_t n = 0;
        err = api_log_read_unum(td, data, &n);
        api_log_print(rec, "%llu", (unsigned long long)n);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_UNUM_HEX:   /* unsigned number printed in hex */
    {
        uint64_t n = 0;
        err = api_log_read_unum(td, data, &n);
        api_log_print(rec, "0x%llx", (unsigned long long)n);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_FLOAT:      /* floating-point number */
    {
        if (td->size == sizeof(float))
        {
            api_log_print(rec, "%f", *(const float *)data);
        }
        else if (td->size == sizeof(double))
        {
            api_log_print(rec, "%f", *(const double *)data);
        }
        else
        {
            err = BCM_ERR_NOT_SUPPORTED;
        }
        break;
    }

    case BCMOLT_BASE_TYPE_ID_BOOL:
    {
        uint64_t n = 0;
        err = api_log_read_unum(td, data, &n);
        api_log_print(rec, "%s", n == 0 ? "no" : "yes");
        break;
    }

    case BCMOLT_BASE_TYPE_ID_STRING:     /* string */
    {
        uint32_t size = td->size;
        if (size == 0)
        {
            size = strlen((const char *)data);
        }
        api_log_print_long_line(rec, (const char *)data, size);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_IPV4:       /* IPv4 address */
    {
        uint32_t ip;
        memcpy(&ip, data, sizeof(ip));
        api_log_print(rec, "%d.%d.%d.%d", (ip>>24)&0xff, (ip>>16)&0xff, (ip>>8)&0xff, ip & 0xff);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_MAC:        /* MAC address */
    {
        bcmos_mac_address mac;
        memcpy(mac.u8, data, sizeof(mac.u8));
        api_log_print(rec, "%02x:%02x:%02x:%02x:%02x:%02x",
            mac.u8[0], mac.u8[1], mac.u8[2], mac.u8[3], mac.u8[4], mac.u8[5]);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_ENUM:       /* enum */
    {
        uint64_t n = 0;
        err = api_log_read_unum(td, data, &n);
        BUG_ON(td->x.e == NULL);
        api_log_print(rec, "%s", bcmcli_enum_stringval(td->x.e, n));
        break;
    }

    case BCMOLT_BASE_TYPE_ID_ENUM_MASK:
    {
        uint64_t n = 0;
        bcmcli_enum_val *value = td->x.e;
        bcmos_bool first = BCMOS_TRUE;
        BUG_ON(value == NULL);
        err = api_log_read_unum(td, data, &n);
        while (value->name != NULL && n != 0)
        {
            if ((value->val & n) != 0)
            {
                api_log_print(rec, "%s%s", first ? "" : "+", value->name);
                first = BCMOS_FALSE;
            }
            n -= value->val;
            ++value;
        }
        if (first)
        {
            api_log_print(rec, "-");
        }
        break;
    }

    default:
        err = BCM_ERR_NOT_SUPPORTED;
        break;
    }
    return err;
}

static uint16_t api_log_get_num_enum_vals(const bcmcli_enum_val *vals)
{
    const bcmcli_enum_val *v = vals;
    while (v != NULL && v->name != NULL)
    {
        ++v;
    }
    return (uint16_t)(v - vals);
}

static bcmos_errno api_log_dump_array(
    api_log_rec *rec,
    const bcmcli_type_descr *td,
    const void *data,
    uint32_t size,
    const char *name)
{
    bcmos_errno err = BCM_ERR_OK;

    /* Print as buffer or element by element ? */
    if ((td->base_type == BCMOLT_BASE_TYPE_ID_UNUM || td->base_type == BCMOLT_BASE_TYPE_ID_UNUM_HEX) && td->size == 1)
    {
        uint32_t i;
        api_log_print(rec, "%s=", name);
        if (size == 0)
        {
            api_log_print(rec, "-");
        }
        else
        {
            for (i = 0; i < size; i++)
            {
                api_log_print(rec, "%02X", ((const uint8_t *)data)[i]);
            }
        }
        api_log_print(rec, " ");
    }
    else
    {
        err = api_log_dump_data_type(rec, td, data, name, size, td->size);
    }
    return err;
}

static bcmos_errno api_log_dump_data_type(
    api_log_rec *rec,
    const bcmcli_type_descr *td,
    const void *data,
    const char *name,
    uint32_t num_entries,
    uint32_t entry_size)
{
    bcmos_errno err = BCM_ERR_OK;

    switch (td->base_type)
    {
        case BCMOLT_BASE_TYPE_ID_STRUCT:
        {
            uint16_t f;
            char full_name[APICLI_MAX_PARM_NAME_LENGTH];
            if (td->x.s.num_fields == 0)
            {
                return 0;
            }
            BUG_ON(td->x.s.fields == NULL);
            for (f = 0; f < td->x.s.num_fields; f++)
            {
                const bcmcli_field_descr *fld = &td->x.s.fields[f];
                void *fdata = (void *)((long)data + fld->offset);
                bcmcli_strncpy(full_name, name, sizeof(full_name));
                bcmcli_strncat(full_name, ".", sizeof(full_name));
                bcmcli_strncat(full_name, fld->name, sizeof(full_name));
                err = api_log_dump_data_type(rec, fld->type, fdata, full_name, num_entries, entry_size);
            }
            break;
        }

        case BCMOLT_BASE_TYPE_ID_UNION:
        {
            /* Print fields up to selector, then selector, then selected sub-structure */
            uint16_t f;
            char full_name[APICLI_MAX_PARM_NAME_LENGTH];
            const bcmcli_field_descr *fld;
            void *fdata;
            int64_t selector_val = 0;
            uint16_t num_union_vals;

            if (td->x.u.num_common_fields == 0)
            {
                return 0;
            }
            BUG_ON(td->x.u.common_fields == NULL);
            /* Common fields, including selector */
            for (f = 0; f <= td->x.u.classifier_idx && err == BCM_ERR_OK; f++)
            {
                fld = &td->x.u.common_fields[f];
                fdata = (void *)((long)data + fld->offset);

                bcmcli_strncpy(full_name, name, sizeof(full_name));
                if (fld->name != NULL && strlen(fld->name) != 0)
                {
                    bcmcli_strncat(full_name, ".", sizeof(full_name));
                    bcmcli_strncat(full_name, fld->name, sizeof(full_name));
                }
                err = api_log_dump_data_type(rec, fld->type, fdata, full_name, num_entries, entry_size);
                if (err == BCM_ERR_OK && f == td->x.u.classifier_idx)
                {
                    err = api_log_read_snum(fld->type, fdata, &selector_val);
                }
            }
            if (err != BCM_ERR_OK)
            {
                return err;
            }

            num_union_vals = api_log_get_num_enum_vals(td->x.u.common_fields[td->x.u.classifier_idx].type->x.e);
            if ((unsigned)selector_val >= num_union_vals)
            {
                return BCM_ERR_INTERNAL;
            }

            /* Selected field */
            fld = &td->x.u.union_fields[selector_val];
            if (fld->type == NULL)
            {
                return BCM_ERR_OK;
            }
            fdata = (void *)((long)data + fld->offset);

            bcmcli_strncpy(full_name, name, sizeof(full_name));
            if (fld->name != NULL && strlen(fld->name) != 0)
            {
                bcmcli_strncat(full_name, ".", sizeof(full_name));
                bcmcli_strncat(full_name, fld->name, sizeof(full_name));
            }
            err = api_log_dump_data_type(rec, fld->type, fdata, full_name, num_entries, entry_size);
            if (err != BCM_ERR_OK)
            {
                return err;
            }

            /* Common fields following selector */
            for (; f < td->x.u.num_common_fields; f++)
            {
                fld = &td->x.u.common_fields[f];
                fdata = (void *)((long)data + fld->offset);

                bcmcli_strncpy(full_name, name, sizeof(full_name));
                if (fld->name != NULL && strlen(fld->name) != 0)
                {
                    bcmcli_strncat(full_name, ".", sizeof(full_name));
                    bcmcli_strncat(full_name, fld->name, sizeof(full_name));
                }
                err = api_log_dump_data_type(rec, fld->type, fdata, full_name, num_entries, entry_size);
            }
            break;
        }

        case BCMOLT_BASE_TYPE_ID_ARR_FIXED:
        {
            err = api_log_dump_array(rec, td->x.arr_fixed.elem_type, data, td->x.arr_fixed.size, name);
            break;
        }

        case BCMOLT_BASE_TYPE_ID_ARR_DYN:
        {
            /* Read length */
            uint32_t array_size;
            long base_ptr;

            switch (td->x.arr_dyn.len_size)
            {
                case 1: array_size = *(const uint8_t *)data; break;
                case 2: array_size = *(const uint16_t *)data; break;
                case 4: array_size = *(const uint32_t *)data; break;
                default:
                    return BCM_ERR_NOT_SUPPORTED;
            }
            base_ptr = BCMOS_ROUND_UP((long)data + td->x.arr_dyn.len_size, sizeof(void *));
            BUG_ON(base_ptr == 0);
            data = *(void **)base_ptr;
            err = api_log_dump_array(rec, td->x.arr_dyn.elem_type, data, array_size, name);
            break;
        }

        default:
        {
            int n;
            /* Finally! Simple type that maps to a single name=value pair */
            if (name != NULL)
            {
                api_log_print(rec, "%s=", name);
            }
            /* Dump simple value or array of simple values */
            if (num_entries == 0)
            {
                api_log_print(rec, "-");
            }
            for (n = 0; n < num_entries; n++)
            {
                if (n != 0)
                {
                    api_log_print(rec, ",");
                }
                err = api_log_dump_simple_data_type(rec, td, data, name);
                if (err != BCM_ERR_OK)
                {
                    return err;
                }
                data = (const void *)((long)data + entry_size);
            }
            api_log_print(rec, " ");
            break;
        }
    }
    return err;
}

static bcmos_errno api_log_dump_prop(api_log_rec *rec, const bcmcli_prop_descr *pd, const void *prop_data)
{
    return api_log_dump_data_type(rec, pd->type, prop_data, pd->name, 1, 0);
}

/* Calculate property pointer given the group data pointer and property description */
static inline const void *api_log_prop_data_ptr(const void *group_ptr, const bcmcli_prop_descr *pd)
{
    return (const void *)((long)group_ptr + pd->offset);
}

static bcmos_errno api_log_append_key(api_log_rec *rec, const void *key, uint32_t key_size)
{
    uint16_t prop;
    bcmos_errno err = BCM_ERR_OK;
    const bcmcli_prop_descr *pd;

    for (prop = 0;
         api_cli_object_property(rec->msg->obj_type, BCMOLT_MGT_GROUP_KEY, 0, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        const void *prop_data = api_log_prop_data_ptr(key, pd);
        if (prop_data == NULL)
        {
            continue;
        }
        BUG_ON(pd->offset > key_size);
        err = api_log_dump_prop(rec, pd, prop_data);
        if (err != BCM_ERR_OK)
        {
            break;
        }
    }
    return err;
}

static bcmos_errno api_log_append_data(api_log_rec *rec, const void *data, uint32_t data_size)
{
    uint16_t prop;
    bcmos_errno err = BCM_ERR_OK;
    const bcmcli_prop_descr *pd;

    for (prop = 0;
         api_cli_object_property(rec->msg->obj_type, rec->msg->group, rec->msg->subgroup, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        const void *prop_data = api_log_prop_data_ptr(data, pd);
        if (((rec->msg->presence_mask & (1LL << prop)) == 0) || (prop_data == NULL))
        {
            continue;
        }
        BUG_ON(pd->offset > data_size);
        err = api_log_dump_prop(rec, pd, prop_data);
        if (err != BCM_ERR_OK)
        {
            break;
        }
    }
    return err;
}

static bcmos_errno api_log_append_hdr(api_log_rec *rec)
{
    bcmos_errno err;
    const char *name;
    const char *descr;

    err = api_cli_object_name(rec->msg->obj_type, &name, &descr);
    if (err != BCM_ERR_OK)
    {
        return err;
    }

    api_log_print(rec, apicli_mgt_group_to_str(rec->msg->group));
    if (api_log_is_singleton(rec->msg->group))
    {
        api_log_print(rec, (rec->msg->type & BCMOLT_MSG_TYPE_SET) != 0 ? "_set" : "_get");
        if ((rec->msg->type & BCMOLT_MSG_TYPE_MULTI) != 0)
        {
            api_log_print(rec, "_multi");
        }
    }

    if (rec->msg->group != BCMOLT_MGT_GROUP_AUTO && rec->msg->group != BCMOLT_MGT_GROUP_PROXY_RX)
    {
        if (rec->msg->dir == BCMOLT_MSG_DIR_REQUEST)
        {
            api_log_print(rec, " request");
        }
        else
        {
            api_log_print(rec, " response[%d]", rec->msg->err);
        }
    }

    api_log_print(rec, "> %s", name);
    if (!api_log_is_singleton(rec->msg->group))
    {
        const char *sub_name;
        const char *sub_d;
        err = api_cli_object_subgroup_name(rec->msg->obj_type, rec->msg->group, rec->msg->subgroup, &sub_name, &sub_d);
        if (err != BCM_ERR_OK)
        {
            return err;
        }
        api_log_print(rec, ".%s", sub_name);
    }

    api_log_print(rec, ": ");

    return BCM_ERR_OK;
}

static bcmos_errno api_log_append_body(api_log_rec *rec)
{
    bcmos_errno err;
    uint32_t key_size;
    uint32_t key_offset;
    uint32_t data_size;
    uint32_t data_offset;

    err = api_cli_object_struct_size(
        rec->msg->obj_type,
        rec->msg->group,
        rec->msg->subgroup,
        &key_size,
        &key_offset,
        &data_size,
        &data_offset);
    if (err != BCM_ERR_OK)
    {
        return err;
    }

    if ((rec->msg->type & BCMOLT_MSG_TYPE_MULTI) != 0)
    {
        /* message set printing for multi-object cfg not implemented */
        api_log_print(rec, "(data omitted)");
    }
    else
    {
        if ((rec->msg->group != BCMOLT_MGT_GROUP_AUTO_CFG) && (key_size != 0))
        {
            const void *key = (const void *)((long)rec->msg + key_offset);
            err = api_log_append_key(rec, key, key_size);
            if (err != BCM_ERR_OK)
            {
                return err;
            }
        }

        if ((data_size != 0) &&
            (((rec->msg->dir == BCMOLT_MSG_DIR_REQUEST) && (rec->msg->type & BCMOLT_MSG_TYPE_SET))  ||
             ((rec->msg->dir == BCMOLT_MSG_DIR_RESPONSE) && (rec->msg->type & BCMOLT_MSG_TYPE_GET)) ||
             (rec->msg->group == BCMOLT_MGT_GROUP_AUTO)                                             ||
             (rec->msg->group == BCMOLT_MGT_GROUP_PROXY_RX)))
        {
            const void *data = (const void *)((long)rec->msg + data_offset);
            err = api_log_append_data(rec, data, data_size);
            if (err != BCM_ERR_OK)
            {
                return err;
            }
        }
    }

    return BCM_ERR_OK;
}

bcmos_errno bcmolt_msg_log(dev_log_id log_id, const bcmolt_msg *msg)
{
    bcmos_errno err = BCM_ERR_OK;
    api_log_rec rec = { .log_id = log_id, .msg = msg, .used = 0 };

    rec.buf = bcmos_blk_pool_alloc(&api_log_blk_pool);
    if (rec.buf == NULL)
    {
        err = BCM_ERR_NOMEM;
    }

    err = (err != BCM_ERR_OK) ? err : api_log_append_hdr(&rec);
    err = (err != BCM_ERR_OK) ? err : api_log_append_body(&rec);
    api_log_flush(&rec, "\n");

    if (rec.buf != NULL)
    {
        bcmos_blk_pool_free(rec.buf);
    }
    if (err != BCM_ERR_OK)
    {
        BCM_LOG(ERROR, log_id, "API message log error: %s (%d)\n", bcmos_strerror(err), err);
    }
    return err;
}

void bcmolt_msg_log_init(void)
{
    bcmos_errno err;
    bcmos_blk_pool_parm blk_pool_parm =
    {
        .name = "api_dev_log",
        .blk_size = MAX_DEV_LOG_STRING_NET_SIZE,
        .num_blks = API_LOG_NUM_BLKS,
    };

    err = bcmos_blk_pool_create(&api_log_blk_pool, &blk_pool_parm);
    BUG_ON(err != BCM_ERR_OK);
}

