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

#include "bcm_api_cli_helpers.h"

typedef enum
{
    APICLI_OUTPUT_STYLE_STD,
    APICLI_OUTPUT_STYLE_C_INIT
} apicli_output_style;

typedef struct
{
    const bcmcli_type_descr *type;
    void *data;
    uint8_t bit;
} apicli_presence_mask_info;

static bcmos_errno _apicli_dump_array(
    bcmcli_session *session,
    const bcmcli_type_descr *td,
    void *data,
    uint32_t size,
    const char *name,
    apicli_output_style style,
    const apicli_presence_mask_info *presence_mask,
    const char *prefix,
    const char *suffix);

static bcmos_errno _apicli_read_snum(bcmcli_session *session, const bcmcli_type_descr *td, void *data, int64_t *n)
{
    switch (td->size)
    {
    case 1:
    {
        int8_t n1 = *(int8_t *)data;
        *n = n1;
        break;
    }
    case 2:
    {
        int16_t n2 = *(int16_t *)data;
        *n = n2;
        break;
    }
    case 4:
    {
        int32_t n4 = *(int32_t *)data;
        *n = n4;
        break;
    }
    case 8:
    {
        memcpy(n, data, sizeof(*n));
        break;
    }
    default:
        bcmcli_print(session, "*** number size %u is not supported\n", td->size);
        return BCM_ERR_NOT_SUPPORTED;
    }
    return BCM_ERR_OK;
}

static bcmos_errno _apicli_read_unum(bcmcli_session *session, const bcmcli_type_descr *td, void *data, uint64_t *n)
{
    switch (td->size)
    {
    case 1:
    {
        uint8_t n1 = *(uint8_t *)data;
        *n = n1;
        break;
    }
    case 2:
    {
        uint16_t n2 = *(uint16_t *)data;
        *n = n2;
        break;
    }
    case 4:
    {
        uint32_t n4 = *(uint32_t *)data;
        *n = n4;
        break;
    }
    case 8:
    {
        memcpy(n, data, sizeof(*n));
        break;
    }
    default:
        bcmcli_print(session, "*** number size %u is not supported\n", td->size);
        return BCM_ERR_NOT_SUPPORTED;
    }
    return BCM_ERR_OK;
}

static void _apicli_strcat_upper(char *dest, uint32_t dest_len, const char *src, uint32_t src_len)
{
    uint32_t src_idx;
    uint32_t dest_idx;

    for (dest_idx = 0; dest_idx < dest_len - 1; ++dest_idx)
    {
        if (dest[dest_idx] == '\0')
        {
            break;
        }
    }

    for (src_idx = 0; src_idx < src_len && dest_idx < dest_len - 1; ++src_idx, ++dest_idx)
    {
        dest[dest_idx] = src[src_idx];
        if (dest[dest_idx] >= 'a' && dest[dest_idx] <= 'z')
        {
            dest[dest_idx] = 'A' + (dest[dest_idx] - 'a');
        }
    }

    dest[dest_idx] = '\0';
}

static const char *_apicli_get_c_enum_id(const bcmcli_type_descr *td, const char *name)
{
    static char full_name_buf[256];
    full_name_buf[0] = '\0';
    _apicli_strcat_upper(full_name_buf, sizeof(full_name_buf), td->name, strlen(td->name));
    _apicli_strcat_upper(full_name_buf, sizeof(full_name_buf), "_", 1);
    _apicli_strcat_upper(full_name_buf, sizeof(full_name_buf), name, strlen(name));
    return full_name_buf;
}

static bcmos_errno _apicli_dump_simple_data_type(
    bcmcli_session *session,
    const bcmcli_type_descr *td,
    void *data,
    const char *name,
    apicli_output_style style)
{
    bcmos_errno rc = BCM_ERR_OK;

    switch (td->base_type)
    {
    case BCMOLT_BASE_TYPE_ID_SNUM:       /* signed number */
    {
        int64_t n = 0;
        rc = _apicli_read_snum(session, td, data, &n);
        bcmcli_print(session, "%lld", (long long)n);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_UNUM:       /* unsigned number */
    {
        uint64_t n = 0;
        rc = _apicli_read_unum(session, td, data, &n);
        bcmcli_print(session, "%llu", (unsigned long long)n);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_UNUM_HEX:   /* unsigned number printed in hex */
    {
        uint64_t n = 0;
        rc = _apicli_read_unum(session, td, data, &n);
        bcmcli_print(session, "0x%llx", (unsigned long long)n);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_FLOAT:      /* floating-point number */
    {
        if (td->size == sizeof(float))
        {
            bcmcli_print(session, "%f", *(float *)data);
        }
        else if (td->size == sizeof(double))
        {
            bcmcli_print(session, "%f", *(double *)data);
        }
        else
        {
            bcmcli_print(session, "*** floating-point number of width %u is not supported\n", td->size);
            rc = BCM_ERR_NOT_SUPPORTED;
        }
        break;
    }

    case BCMOLT_BASE_TYPE_ID_BOOL:
    {
        const char *no_str = style == APICLI_OUTPUT_STYLE_C_INIT ? "BCMOS_FALSE" : "no";
        const char *yes_str = style == APICLI_OUTPUT_STYLE_C_INIT ? "BCMOS_TRUE" : "yes";
        uint64_t n = 0;
        rc = _apicli_read_unum(session, td, data, &n);
        bcmcli_print(session, "%s", n == 0 ? no_str : yes_str);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_STRING:     /* string */
    {
        if (td->size == 0)
        {
            bcmcli_print(session, "\"%s\"", (char *)data);
        }
        else
        {
            /* we know the size of the buffer */
            bcmcli_print(session, "\"%.*s\"", td->size, (char *)data);
        }
        break;
    }

    case BCMOLT_BASE_TYPE_ID_IPV4:       /* IPv4 address */
    {
        uint32_t ip;
        memcpy(&ip, data, sizeof(ip));
        bcmcli_print(
            session,
            style == APICLI_OUTPUT_STYLE_C_INIT ? "{ %d,%d,%d,%d }" : "%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));
        bcmcli_print(
            session,
            style == APICLI_OUTPUT_STYLE_C_INIT ?
                "{{ 0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x }}" :
                "%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;
        const char *s;
        rc = _apicli_read_unum(session, td, data, &n);
        BUG_ON(td->x.e == NULL);
        s = bcmcli_enum_stringval(td->x.e, (long)n);
        if (style == APICLI_OUTPUT_STYLE_C_INIT)
        {
            s = _apicli_get_c_enum_id(td, s);
        }
        bcmcli_print(session, "%s", s);
        break;
    }

    case BCMOLT_BASE_TYPE_ID_ENUM_MASK:
    {
        uint64_t n = 0;
        const char *s;
        const char *none = NULL;
        bcmcli_enum_val *value = td->x.e;
        bcmos_bool first = BCMOS_TRUE;
        BUG_ON(value == NULL);
        rc = _apicli_read_unum(session, td, data, &n);
        while (value->name != NULL)
        {
            if (value->val == 0)
            {
                none = value->name;
            }
            if ((value->val & n) != 0)
            {
                s = value->name;
                if (style == APICLI_OUTPUT_STYLE_C_INIT)
                {
                    s = _apicli_get_c_enum_id(td, s);
                }
                bcmcli_print(session, "%s%s", first ? "" : (style == APICLI_OUTPUT_STYLE_C_INIT ? "|" : BCMCLI_ENUM_MASK_DEL_STR), s);
                first = BCMOS_FALSE;
                n -= value->val;
            }
            ++value;
        }
        if (first)
        {
            bcmcli_print(session, "%s", (style == APICLI_OUTPUT_STYLE_C_INIT) || (NULL == none) ? "0" : none);
        }
        break;
    }

    default:
        bcmcli_print(session, "*** type %d is not supported\n", (int)td->base_type);
        rc = BCM_ERR_NOT_SUPPORTED;
        break;
    }
    return rc;
}


/* calculate number of enum values */
static int _api_cli_get_num_enum_vals(const bcmcli_enum_val *vals)
{
    const bcmcli_enum_val *v = vals;
    while (v && v->name)
    {
        ++v;
    }
    return (v - vals);
}

/* helper function to skip the "u." in front of union field names */
static inline const char *_apicli_skip_union_prefix(const char *name)
{
    if (name[0] == 'u' && name[1] == '.')
    {
        name += 2;
    }
    return name;
}

static bcmos_bool _apicli_is_value_set(bcmcli_session *session, const apicli_presence_mask_info *presence_mask)
{
    uint64_t pm_value_num = 0;
    if (!presence_mask || !presence_mask->type)
    {
        /* no presence mask - all values are implicitly set */
        return BCMOS_TRUE;
    }
    _apicli_read_unum(session, presence_mask->type, presence_mask->data, &pm_value_num);
    return ((pm_value_num >> presence_mask->bit) & 1) != 0;
}

static bcmos_errno _apicli_arr_dyn_len_get(const bcmcli_type_descr *td, void *data, uint32_t *array_size)
{
    switch (td->x.arr_dyn.len_size)
    {
    case 1: *array_size = *(uint8_t *)data; break;
    case 2: *array_size = *(uint16_t *)data; break;
    case 4: *array_size = *(uint32_t *)data; break;
    default: return BCM_ERR_NOT_SUPPORTED;
    }

    return BCM_ERR_OK;
}

static void *_apicli_arr_dyn_data_get(const bcmcli_type_descr *td, void *data)
{
    return *(void**)BCMOS_ROUND_UP((long)data + td->x.arr_dyn.len_size, sizeof(void *));
}

/* Dump data type */
static bcmos_errno _apicli_dump_data_type(
    bcmcli_session *session,
    const bcmcli_type_descr *td,
    void *data,
    const char *name,
    uint32_t num_entries,
    uint32_t entry_size,
    apicli_output_style style,
    const apicli_presence_mask_info *presence_mask,
    const char *prefix,
    const char *suffix)
{
    bcmos_errno rc = 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)
                return 0;
            BUG_ON(!td->x.s.fields);
            if (style == APICLI_OUTPUT_STYLE_C_INIT)
            {
                bcmcli_print(session, "{ ");
            }
            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);
                apicli_presence_mask_info field_pm = {};
                if (((td->x.s.fields[0].flags & BCMCLI_FIELD_DESCR_FLAGS_PRESENCE_MASK) != 0) &&
                    style != APICLI_OUTPUT_STYLE_C_INIT)
                {
                    /* If the struct has a presence mask, skip the presence mask field itself, then record the position
                     * of the presence mask so we can check it later for each entry. */
                    if (f == 0)
                    {
                        continue;
                    }

                    field_pm.type = td->x.s.fields[0].type;
                    field_pm.data = (uint8_t *)data + td->x.s.fields[0].offset;
                    field_pm.bit = (uint8_t)(f - 1);
                }
                if (style == APICLI_OUTPUT_STYLE_C_INIT && f > 0)
                {
                    bcmcli_print(session, ", ");
                }
                bcmcli_strncpy(full_name, name, sizeof(full_name));
                bcmcli_strncat(full_name, ".", sizeof(full_name));
                bcmcli_strncat(full_name, fld->name, sizeof(full_name));
                rc = _apicli_dump_data_type(session, fld->type, fdata, full_name, num_entries, entry_size, style, &field_pm, prefix, suffix);
            }
            if (style == APICLI_OUTPUT_STYLE_C_INIT)
            {
                bcmcli_print(session, " }");
            }
            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;
            int num_union_vals;

            if (!td->x.u.num_common_fields)
                return 0;
            BUG_ON(!td->x.u.common_fields);
            if (style == APICLI_OUTPUT_STYLE_C_INIT)
            {
                bcmcli_print(session, "{ ");
            }
            /* Common fields, including selector */
            for (f = 0; f <= td->x.u.classifier_idx && !rc; 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 && strlen(fld->name))
                {
                    bcmcli_strncat(full_name, ".", sizeof(full_name));
                    bcmcli_strncat(full_name, fld->name, sizeof(full_name));
                }
                rc = _apicli_dump_data_type(session, fld->type, fdata, full_name, num_entries, entry_size, style, presence_mask, prefix, suffix);
                if (f == td->x.u.classifier_idx)
                {
                    rc = rc ? rc : _apicli_read_snum(session, fld->type, fdata, &selector_val);
                }
                if (style == APICLI_OUTPUT_STYLE_C_INIT)
                {
                    bcmcli_print(session, ", ");
                }
            }
            if (rc)
            {
                bcmcli_print(session, "***internal error when dumping field %s\n",
                    td->x.u.common_fields[f].name);
                return rc;
            }

            num_union_vals = _api_cli_get_num_enum_vals(td->x.u.common_fields[td->x.u.classifier_idx].type->x.e);
            if ((unsigned)selector_val >= num_union_vals)
            {
                bcmcli_print(session, "***invalid union selector value %lld\n", (long long)selector_val);
                return BCM_ERR_INTERNAL;
            }

            /* 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);

                if (style == APICLI_OUTPUT_STYLE_C_INIT)
                {
                    bcmcli_print(session, ", ");
                }
                bcmcli_strncpy(full_name, name, sizeof(full_name));
                if (fld->name && strlen(fld->name))
                {
                    bcmcli_strncat(full_name, ".", sizeof(full_name));
                    bcmcli_strncat(full_name, fld->name, sizeof(full_name));
                }
                rc = _apicli_dump_data_type(session, fld->type, fdata, full_name, num_entries, entry_size, style, presence_mask, prefix, suffix);
            }

            /* Selected field */
            fld = &td->x.u.union_fields[selector_val];
            if (fld->type)
            {
                if (style == APICLI_OUTPUT_STYLE_C_INIT)
                {
                    bcmcli_print(session, "{ .%s = ", _apicli_skip_union_prefix(fld->name));
                }
                fdata = (void *)((long)data + fld->offset);

                bcmcli_strncpy(full_name, name, sizeof(full_name));
                if (fld->name && strlen(fld->name))
                {
                    bcmcli_strncat(full_name, ".", sizeof(full_name));
                    bcmcli_strncat(full_name, fld->name, sizeof(full_name));
                }
                rc = _apicli_dump_data_type(session, fld->type, fdata, full_name, num_entries, entry_size, style, presence_mask, prefix, suffix);
                if (style == APICLI_OUTPUT_STYLE_C_INIT)
                {
                    bcmcli_print(session, " }");
                }
            }
            if (style == APICLI_OUTPUT_STYLE_C_INIT)
            {
                bcmcli_print(session, " }");
            }
            break;
        }

        case BCMOLT_BASE_TYPE_ID_ARR_FIXED: /* fixed array */
        {
            rc = _apicli_dump_array(session, td->x.arr_fixed.elem_type, data, td->x.arr_fixed.size, name, style, presence_mask, prefix, suffix);
            break;
        }

        case BCMOLT_BASE_TYPE_ID_ARR_DYN:   /* dynamic array that should be printed as buffer */
        {
            /* Read length */
            uint32_t array_size;

            rc = _apicli_arr_dyn_len_get(td, data, &array_size);
            if (BCM_ERR_OK != rc)
            {
                    bcmcli_print(session, "*** %s: dyn array len_size %u is not supported\n", name, td->x.arr_dyn.len_size);
                return rc;
            }

            if (style == APICLI_OUTPUT_STYLE_C_INIT)
            {
                const char *field_name = strrchr(name, '.');
                if (field_name == NULL)
                {
                    field_name = name;
                }
                else
                {
                    ++field_name;
                }
                bcmcli_print(session, "{ %u, %s }", array_size, field_name);
            }
            else
            {
            data = _apicli_arr_dyn_data_get(td, data);
            rc = _apicli_dump_array(session, td->x.arr_dyn.elem_type, data, array_size, name, style, presence_mask, prefix, suffix);
            }
            break;
        }

        default:
        {
            /* Finally! Simple type that maps to a single CLI parameter */
            int n;
            apicli_presence_mask_info local_pm;

            /* If we have a single value and that value is not included in the presence mask, just skip it entirely */
            if (num_entries == 1 && !_apicli_is_value_set(session, presence_mask))
            {
                break;
            }

            if (style != APICLI_OUTPUT_STYLE_C_INIT)
            {
                if (name)
                {
                    bcmcli_print(session, "%s%s=", prefix, name);
                }
                if (!num_entries)
                {
                    bcmcli_print(session, BCMCLI_ARRAY_EMPTY);
                }
            }

            /* Dump simple value or array of simple values */
            local_pm = presence_mask ? *presence_mask : (apicli_presence_mask_info){};
            for (n = 0; n < num_entries; n++)
            {
                if (n)
                {
                    bcmcli_print(session, ",");
                }

                /* If we have a presence mask, make sure to print a special token if the value is unset */
                if (_apicli_is_value_set(session, &local_pm))
                {
                    rc = _apicli_dump_simple_data_type(session, td, data, name, style);
                }
                else
                {
                    bcmcli_print(session, BCMCLI_PARM_NO_VALUE);
                }

                data = (void *)((long)data + entry_size);
                local_pm.data = (void *)((long)local_pm.data + entry_size);
            }
            bcmcli_print(session, "%s", suffix);
            break;
        }
    }
    return rc;
}

/* Dump array */
static bcmos_errno _apicli_dump_array(
    bcmcli_session *session,
    const bcmcli_type_descr *td,
    void *data,
    uint32_t size,
    const char *name,
    apicli_output_style style,
    const apicli_presence_mask_info *presence_mask,
    const char *prefix,
    const char *suffix)
{
    bcmos_errno rc = BCM_ERR_OK;

    /* Print as buffer or element by element ? */
    if (style == APICLI_OUTPUT_STYLE_C_INIT)
    {
        bcmcli_print(session, "{ ");
        rc = _apicli_dump_data_type(session, td, data, name, size, td->size, style, presence_mask, prefix, suffix);
        bcmcli_print(session, " }");
    }
    else if ((td->base_type == BCMOLT_BASE_TYPE_ID_UNUM || td->base_type == BCMOLT_BASE_TYPE_ID_UNUM_HEX) && td->size == 1)
    {
        if (_apicli_is_value_set(session, presence_mask))
        {
            uint32_t i;

            bcmcli_print(session, "%s%s=", prefix, name);
            for (i = 0; i < size; ++i)
            {
                bcmcli_print(session, "%02x", ((uint8_t*)data)[i]);
            }
            bcmcli_print(session, "%s", suffix);
        }
    }
    else
    {
        rc = _apicli_dump_data_type(session, td, data, name, size, td->size, style, presence_mask, prefix, suffix);
    }
    return rc;
}

/* Dump property */
bcmos_errno apicli_dump_prop(bcmcli_session *session, const bcmcli_prop_descr *pd, void *prop_data)
{
    return _apicli_dump_data_type(session, pd->type, prop_data, pd->name, 1, 0, APICLI_OUTPUT_STYLE_STD, NULL, "   ", "\n");
}

/* Dump a single property value in C initializer format */
bcmos_errno apicli_dump_prop_initializer(bcmcli_session *session, const bcmcli_prop_descr *pd, void *prop_data)
{
    return _apicli_dump_data_type(session, pd->type, prop_data, pd->name, 1, 0, APICLI_OUTPUT_STYLE_C_INIT, NULL, "", "");
}

bcmos_errno apicli_dump_dyn_array(
    bcmcli_session *session,
    const bcmcli_type_descr *td,
    void *data,
    const char *name)
{
    bcmos_errno rc;
    uint32_t array_size;

    rc = _apicli_arr_dyn_len_get(td, data, &array_size);
    BCMOS_RETURN_IF_ERROR(rc);
    return _apicli_dump_array(
        session,
        td->x.arr_dyn.elem_type,
        _apicli_arr_dyn_data_get(td, data),
        array_size,
        name,
        APICLI_OUTPUT_STYLE_C_INIT,
        NULL,
        "",
        "");
}

/* Dump property as CLI parameters */
bcmos_errno apicli_dump_prop_param(bcmcli_session *session, const bcmcli_prop_descr *pd, void *prop_data, const char *prefix)
{
    return _apicli_dump_data_type(session, pd->type, prop_data, pd->name, 1, 0, APICLI_OUTPUT_STYLE_STD, NULL, prefix, "");
}

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

/* Dump object data */
static bcmos_errno _apicli_dump_data(bcmcli_session *session, bcmolt_msg *msg, void *data, uint32_t data_size)
{
    uint16_t prop;
    bcmos_errno rc = BCM_ERR_OK;
    const bcmcli_prop_descr *pd;

    bcmcli_print(session, "data:\n");
    for (prop = 0;
         api_cli_object_property(msg->obj_type, msg->group, msg->subgroup, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        void *prop_data = _apicli_prop_data_ptr(data, pd);
        if (!(msg->presence_mask & (1LL << prop)))
            continue;
        if (!prop_data)
        {
            continue;
        }
        BUG_ON(pd->offset > data_size);
        rc = apicli_dump_prop(session, pd, prop_data);
        if (rc != BCM_ERR_OK)
        {
            break;
        }
    }
    return rc;
}

/* Dump object key */
static bcmos_errno _apicli_dump_key(bcmcli_session *session, bcmolt_msg *msg, void *key, uint32_t key_size)
{
    uint16_t prop;
    bcmos_errno rc = BCM_ERR_OK;
    const bcmcli_prop_descr *pd;

    bcmcli_print(session, "key:\n");
    for (prop = 0;
         api_cli_object_property(msg->obj_type, BCMOLT_MGT_GROUP_KEY, 0, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        void *prop_data = _apicli_prop_data_ptr(key, pd);
        if (!prop_data)
        {
            continue;
        }
        BUG_ON(pd->offset > key_size);
        rc = apicli_dump_prop(session, pd, prop_data);
        if (rc != BCM_ERR_OK)
        {
            break;
        }
    }
    return rc;
}

const char *apicli_mgt_group_to_str(bcmolt_mgt_group group)
{
    static const char *str_table[BCMOLT_MGT_GROUP__NUM_OF] =
    {
        [BCMOLT_MGT_GROUP_KEY]      = "key",
        [BCMOLT_MGT_GROUP_CFG]      = "cfg",
        [BCMOLT_MGT_GROUP_STAT]     = "stat",
        [BCMOLT_MGT_GROUP_STAT_CFG] = "stat_cfg",
        [BCMOLT_MGT_GROUP_AUTO]     = "auto",
        [BCMOLT_MGT_GROUP_AUTO_CFG] = "auto_cfg",
        [BCMOLT_MGT_GROUP_OPER]     = "oper",
        [BCMOLT_MGT_GROUP_PROXY]    = "proxy",
        [BCMOLT_MGT_GROUP_PROXY_RX] = "proxy_rx"
    };
    return (group >= BCMOLT_MGT_GROUP__NUM_OF) ? "<unknown>" : str_table[group];
}

/* Dump message set returned by multi-object GET */
static bcmos_errno _apicli_dump_msgset(
    bcmcli_session *session,
    bcmolt_msg *msg,
    uint32_t key_size,
    uint32_t data_size,
    uint32_t data_offset)
{
    uint16_t inst;
    bcmos_errno rc;
    void *key = NULL;
    void *data = NULL;

    if (msg->msg_set == NULL)
    {
        return BCM_ERR_NULL;
    }

    bcmcli_print(session, "more: %s\n", msg->msg_set->more ? "yes" : "no");
    if (msg->msg_set->more)
    {
        bcmcli_print(session, "next ");
        _apicli_dump_key(session, msg, msg->msg_set->next_key, key_size);
    }

    bcmcli_print(session, "number of objects returned: %d\n", msg->msg_set->num_instances);
    for (inst = 0; inst < msg->msg_set->num_instances; inst++)
    {
        bcmcli_print(session, "object %d:\n", inst);

        key = (void *)((long)msg->msg_set->msg[inst] + sizeof(bcmolt_msg));
        rc = _apicli_dump_key(session, msg->msg_set->msg[inst], key, key_size);
        if (rc != BCM_ERR_OK)
        {
            return rc;
        }

        data = (void *)((long)msg->msg_set->msg[inst] + data_offset);
        rc = _apicli_dump_data(session, msg->msg_set->msg[inst], data, data_size);
        if (rc)
        {
            return rc;
        }
    }

    return BCM_ERR_OK;
}

/* Dump message */
bcmos_errno apicli_msg_dump(bcmcli_session *session, bcmolt_msg *msg)
{
    bcmos_errno rc;
    const char *name, *descr;
    uint32_t key_size;
    uint32_t key_offset;
    uint32_t data_size;
    uint32_t data_offset;
    void *key = NULL;
    void *data = NULL;

    rc = api_cli_object_name(msg->obj_type, &name, &descr);
    if (rc)
    {
        goto dump_error;
    }

    bcmcli_print(session, "object: ");
    if (name)
    {
        bcmcli_print(session, "%s", name);
    }
    if (descr)
    {
        bcmcli_print(session, " - %s", descr);
    }
    bcmcli_print(session, "\n");
    rc = api_cli_object_struct_size(
        msg->obj_type,
        msg->group,
        msg->subgroup,
        &key_size,
        &key_offset,
        &data_size,
        &data_offset);
    if (rc)
    {
        goto dump_error;
    }

    bcmcli_print(session, (msg->type & BCMOLT_MSG_TYPE_GET) != 0 ? "get" : "set");
    if ((msg->type & BCMOLT_MSG_TYPE_CLEAR) != 0)
    {
        bcmcli_print(session, ",clear");
    }
    if ((msg->type & BCMOLT_MSG_TYPE_MULTI) != 0)
    {
        bcmcli_print(session, ",multi");
    }
    bcmcli_print(session, " %s ", apicli_mgt_group_to_str(msg->group));

    if (msg->group != BCMOLT_MGT_GROUP_CFG && msg->group != BCMOLT_MGT_GROUP_STAT &&
        msg->group != BCMOLT_MGT_GROUP_AUTO_CFG && msg->group != BCMOLT_MGT_GROUP_STAT_CFG)
    {
        const char *sub_name, *sub_descr;
        /* Get name of specific subgroup */
        rc = api_cli_object_subgroup_name(msg->obj_type, msg->group, msg->subgroup, &sub_name, &sub_descr);
        if (rc)
        {
            goto dump_error;
        }
        bcmcli_print(session, "subgroup: %s-%s ", sub_name ? sub_name : "?", sub_descr ? sub_descr : "");
    }
    if (msg->dir == BCMOLT_MSG_DIR_REQUEST)
    {
        bcmcli_print(session, "request\n");
    }
    else
    {
        bcmcli_print(session, "response: %s %s\n", bcmos_strerror(msg->err), msg->err_text);
    }

    if (msg->dir == BCMOLT_MSG_DIR_RESPONSE && (msg->type & BCMOLT_MSG_TYPE_MULTI) != 0)
    {
        rc = _apicli_dump_msgset(session, msg, key_size, data_size, data_offset);
        if (rc)
        {
            goto dump_error;
        }
    }
    else
    {
        if ((msg->group != BCMOLT_MGT_GROUP_AUTO_CFG) && key_size)
        {
            key = (void *)((long)msg + key_offset);
            rc = _apicli_dump_key(session, msg, key, key_size);
            if (rc)
            {
                goto dump_error;
            }
        }
        if (data_size &&
             (  ((msg->dir == BCMOLT_MSG_DIR_REQUEST) && (msg->type & BCMOLT_MSG_TYPE_SET))  ||
                ((msg->dir == BCMOLT_MSG_DIR_RESPONSE) && (msg->type & BCMOLT_MSG_TYPE_GET)) ||
                (msg->group == BCMOLT_MGT_GROUP_AUTO)                                        ||
                (msg->group == BCMOLT_MGT_GROUP_PROXY_RX)
             )
           )
        {
            data = (void *)((long)msg + data_offset);
            rc = _apicli_dump_data(session, msg, data, data_size);
            if (rc)
            {
                goto dump_error;
            }
        }
    }
    return BCM_ERR_OK;

dump_error:
    bcmcli_print(session, "*** Object dump error %s (%d)\n", bcmos_strerror(rc), rc);
    return rc;
}

