/*
<: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 <bcmcli.h>
#include <bcmolt_api.h>
#include <bcmolt_model_types.h>
#include <bcmos_types.h>

#include "bcm_api_cli.h"
#include "bcm_api_cli_helpers.h"
#include "bcm_api_cli_handlers.h"
#ifdef BCM_SUBSYSTEM_HOST
#include <bcmolt_dev_selector.h>
#endif

#define APICLI_CAST_DISCARD_CONST(p, type)       (type)((long)(p))

/* bool enum table */
static bcmcli_enum_val bool_enum[] =
{
    { .name = "yes", .val = 1 },
    { .name = "no", .val = 0 },
    BCMCLI_ENUM_LAST
};

static bcmcli_type_descr bool_type_descr = {
    .name = "bool",
    .descr = "Boolean",
    .base_type = BCMOLT_BASE_TYPE_ID_ENUM,
    .size = sizeof(bcmos_bool),
    .x = {.e = bool_enum}
};

/* parameter data */
typedef struct
{
    const bcmcli_prop_descr *prop;      /* property */
    const bcmcli_field_descr *field;    /* field or NULL */
    const bcmcli_field_descr *array_fd; /* array field descriptor or NULL */
    uint16_t offset;                    /* offset from the beginning of the property */
    uint16_t array_fd_offset;           /* offset of array_fd from the beginning of the property */
    bcmolt_mgt_group group;             /* management group */
} apicli_parm_data;

typedef enum
{
    API_CLI_FLAGS_NONE = 0,
    API_CLI_FLAGS_IGNORE_FIELDS = 1 << 0,
    API_CLI_FLAGS_MULTI = 1 << 1
} api_cli_flags;

/* Operation: set, get, modify */
typedef enum
{
    API_CLI_OPER_SET,
    API_CLI_OPER_GET,
    API_CLI_OPER_MODIFY,
} api_cli_oper;

/* Current session */
static bcmcli_session *current_session;

/* Current system mode */
static bcmolt_system_mode current_system_mode;

/* Parent directory */
static bcmcli_entry *api_parent_dir;

/*
 * helpers
 */

/* calculate number of fields in type */
static uint32_t _api_cli_get_num_fields_in_type(const bcmcli_type_descr *td)
{
    uint16_t f;
    uint32_t nf = 0;


    switch (td->base_type)
    {
        case BCMOLT_BASE_TYPE_ID_STRUCT:
        {
            if (!td->x.s.num_fields)
                return 0;
            BUG_ON(!td->x.s.fields);
            for (f = 0; f < td->x.s.num_fields; f++)
            {
                nf +=  _api_cli_get_num_fields_in_type(td->x.s.fields[f].type);
            }
            break;
        }

        case BCMOLT_BASE_TYPE_ID_UNION:
        {
            /* Union. Count only common fields */
            nf = td->x.u.num_common_fields;
            break;
        }

        case BCMOLT_BASE_TYPE_ID_ARR_FIXED:
        {
            nf = _api_cli_get_num_fields_in_type(td->x.arr_fixed.elem_type);
            break;
        }

        case BCMOLT_BASE_TYPE_ID_ARR_DYN:
        {
            nf = _api_cli_get_num_fields_in_type(td->x.arr_dyn.elem_type);
            break;
        }

        default:
        {
            nf = 1;
            break;
        }
    }

    return nf;
}

/* calculate number of property fields for given object+group+subgroup+access. simple property=single field */
static bcmos_errno _api_cli_get_num_fields_in_group(bcmolt_obj_id o, bcmolt_mgt_group group, uint16_t subgroup,
    bcmolt_prop_access_id access_level, uint32_t *nfields)
{
    uint32_t nf = 0;
    int i;
    bcmos_errno rc = BCM_ERR_OK;

    for (i = 0; rc != BCM_ERR_RANGE; i++)
    {
        const bcmcli_prop_descr *pd;
        rc = api_cli_object_property(o, group, subgroup, i, &pd);
        if (rc == BCM_ERR_OK && (pd->access & access_level))
        {
            /* Calculate number of fields if write access. Count only properties for read access */
            if ((access_level & BCMOLT_PROP_ACCESS_ID_W) != 0)
            {
                BUG_ON(!pd->type);
                nf += _api_cli_get_num_fields_in_type(pd->type);
            }
            else
            {
                ++nf;
            }
        }
    }
    *nfields = nf;

    return BCM_ERR_OK;
}

/*
 * Command handlers
 */

static bcmos_errno _apicli_objects_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    int rc;
    bcmolt_obj_id o;
    const char *name, *descr;

    bcmcli_print(session, "System Object Types:\n");
    bcmcli_print(session, "=======================================\n");
    bcmcli_print(session, "Id   Name                   Description\n");
    bcmcli_print(session, "=======================================\n");
    for (o = 0; o < BCMOLT_OBJ_ID__NUM_OF; o++)
    {

        if (current_system_mode < BCMOLT_SYSTEM_MODE__NUM_OF && !bcmolt_object_is_supported(current_system_mode, o))
            continue;

        rc = api_cli_object_name(o, &name, &descr);
        if (!rc)
            bcmcli_print(session, "%.4d %-22s %s\n", o, name, descr);
    }

    return 0;
}

static bcmos_errno _apicli_set_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_CFG, BCMOLT_MSG_TYPE_SET, session);
}

static bcmos_errno _apicli_get_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_CFG, BCMOLT_MSG_TYPE_GET, session);
}

static bcmos_errno _apicli_clear_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_CFG, BCMOLT_MSG_TYPE_CLEAR, session);
}

static bcmos_errno _apicli_stat_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_STAT, BCMOLT_MSG_TYPE_GET, session);
}

static bcmos_errno _apicli_oper_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_OPER, BCMOLT_MSG_TYPE_SET, session);
}

static bcmos_errno _apicli_send_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_PROXY, BCMOLT_MSG_TYPE_SET, session);
}

static bcmos_errno _apicli_stat_cfg_set_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_STAT_CFG, BCMOLT_MSG_TYPE_SET, session);
}

static bcmos_errno _apicli_stat_cfg_get_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_STAT_CFG, BCMOLT_MSG_TYPE_GET, session);
}

static bcmos_errno _apicli_auto_cfg_set_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_AUTO_CFG, BCMOLT_MSG_TYPE_SET, session);
}

static bcmos_errno _apicli_auto_cfg_get_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_AUTO_CFG, BCMOLT_MSG_TYPE_GET, session);
}

static bcmos_errno _apicli_auto_cfg_get_multi_handler(
    bcmcli_session *session,
    const bcmcli_cmd_parm parm[],
    uint16_t nparms)
{
    return bcmolt_cli_api_call(current_device, BCMOLT_MGT_GROUP_CFG, BCMOLT_MSG_TYPE_GET_MULTI, session);
}

/*
 * Init-time helpers
 */

/* map to CLI type */
static bcmos_errno _api_cli_map_type(const bcmcli_type_descr *td, const bcmcli_type_descr *array_td, bcmcli_cmd_parm *cmd_parm)
{
    apicli_parm_data *parm_data = cmd_parm->user_data;
    bcmos_errno rc = BCM_ERR_OK;

    /* Map type */
    switch(td->base_type)
    {
    case BCMOLT_BASE_TYPE_ID_SNUM:
        cmd_parm->type = BCMCLI_PARM_NUMBER;
        break;
    case BCMOLT_BASE_TYPE_ID_UNUM:
        cmd_parm->type = BCMCLI_PARM_UNUMBER;
        break;
    case BCMOLT_BASE_TYPE_ID_UNUM_HEX:
        cmd_parm->type = BCMCLI_PARM_HEX;
        break;
    case BCMOLT_BASE_TYPE_ID_BOOL:
        cmd_parm->type = BCMCLI_PARM_ENUM;
        cmd_parm->enum_table = bool_enum;
        break;
    case BCMOLT_BASE_TYPE_ID_FLOAT:
        cmd_parm->type = td->size == sizeof(double) ? BCMCLI_PARM_DOUBLE : BCMCLI_PARM_FLOAT;
        break;
    case BCMOLT_BASE_TYPE_ID_STRING:
        cmd_parm->type = BCMCLI_PARM_STRING;
        break;
    case BCMOLT_BASE_TYPE_ID_IPV4:
        cmd_parm->type = BCMCLI_PARM_IP;
        break;
    case BCMOLT_BASE_TYPE_ID_MAC:
        cmd_parm->type = BCMCLI_PARM_MAC;
        break;
    case BCMOLT_BASE_TYPE_ID_ENUM:
        cmd_parm->type = BCMCLI_PARM_ENUM;
        cmd_parm->enum_table = td->x.e;
        break;
    case BCMOLT_BASE_TYPE_ID_ENUM_MASK:
        cmd_parm->type = BCMCLI_PARM_ENUM_MASK;
        cmd_parm->enum_table = td->x.e;
        break;
    default:
        bcmcli_print(current_session, "*** can't map type %s (%d)\n", td->name, (int)td->base_type);
        rc = BCM_ERR_NOT_SUPPORTED;
        break;
    }

    /* Map uint8_t array to buffer if it is independent (not structure field) */
    if (array_td &&
        td->size == 1 &&
        (td->base_type == BCMOLT_BASE_TYPE_ID_UNUM || td->base_type == BCMOLT_BASE_TYPE_ID_UNUM_HEX) &&
        (parm_data->array_fd == parm_data->field || !parm_data->field))
    {
        cmd_parm->type = BCMCLI_PARM_BUFFER;
    }

    return rc;
}

/* allocate memory for name and description and copy to to parm */
static bcmos_errno _api_cli_copy_parm_name(bcmcli_cmd_parm *parm, const char *name, const char *descr)
{
    parm->name = bcmos_alloc(strlen(name) + 1);
    parm->description = bcmos_alloc(strlen(descr) + 1);
    if ((parm->name == NULL) || (parm->description == NULL))
    {
        /* Successful allocation if any will be released by common cleanup
         * along with the rest of dynamic parameter fields */
        return BCM_ERR_NOMEM;
    }
    strcpy(APICLI_CAST_DISCARD_CONST(parm->name, void *), name);
    strcpy(APICLI_CAST_DISCARD_CONST(parm->description, void *), descr);
    return BCM_ERR_OK;
}

/* populate single parameter */
static int _api_cli_populate_parm1(const bcmcli_prop_descr *pd, const bcmcli_field_descr *fd, const bcmcli_type_descr *td,
    const bcmcli_field_descr *array_fd, uint32_t offset, uint32_t array_fd_offset,
    bcmcli_cmd_parm *cmd_parm, uint32_t cmd_flags, char *name, char *help)
{
    apicli_parm_data *parm_data = cmd_parm->user_data;
    int rc;

    parm_data->prop = pd;
    parm_data->field = fd;
    parm_data->offset = offset;
    parm_data->array_fd = array_fd;
    parm_data->array_fd_offset = array_fd_offset;

    rc = _api_cli_copy_parm_name(cmd_parm, name, help);
    if (rc)
    {
        return rc;
    }
    cmd_parm->flags = cmd_flags;
    if (td->min_val != td->max_val || td->min_val)
    {
        cmd_parm->flags |= BCMCLI_PARM_FLAG_RANGE;
        cmd_parm->low_val = td->min_val;
        cmd_parm->hi_val = td->max_val;
    }
    rc = _api_cli_map_type(td, array_fd ? array_fd->type : NULL, cmd_parm);
    if (rc < 0)
    {
        return rc;
    }

    /* Arrays require more work.
     * - Calculate size. Known for fixed arrays, hard-coded max for dynamic
     * - Allocate either buffer or array of values based on CLI parameter type
     * - Calculate offset from the beginning of array entry
     */
    if (array_fd)
    {
        uint32_t array_size;

        if (array_fd->type->base_type == BCMOLT_BASE_TYPE_ID_ARR_FIXED)
        {
            array_size = array_fd->type->x.arr_fixed.size;
        }
        else
        {
            array_size = array_fd->type->x.arr_dyn.max_size;
        }
        if (!array_size)
        {
            bcmcli_print(current_session, "*** Error in %s array descriptor. Size is not set.\n", array_fd->name);
            return BCM_ERR_INTERNAL;
        }
        if (cmd_parm->type == BCMCLI_PARM_BUFFER)
        {
            rc = bcmolt_buf_alloc(&cmd_parm->value.buffer, array_size, BCMOLT_BUF_ENDIAN_FIXED);
            if (rc)
            {
                return rc;
            }
        }
        else
        {
            cmd_parm->values = bcmos_calloc(sizeof(bcmcli_parm_value) * array_size);
            if (!cmd_parm->values)
            {
                return BCM_ERR_NOMEM;
            }
            cmd_parm->max_array_size = array_size;
        }
    }

    return 1;
}


/* populate name buf and help buf */
static void _api_cli_populate_name_help(const bcmcli_field_descr *fld, char *name_buf0, char *help_buf0,
    char *name_buf, char *help_buf)
{
    name_buf[0] = 0;
    help_buf[0] = 0;
    bcmcli_strncpy(name_buf, name_buf0, APICLI_MAX_PARM_NAME_LENGTH);
    if (strlen(name_buf))
        bcmcli_strncat(name_buf, ".", APICLI_MAX_PARM_NAME_LENGTH);
    bcmcli_strncat(name_buf, fld->cli_name ? fld->cli_name : fld->name, APICLI_MAX_PARM_NAME_LENGTH);
    bcmcli_strncpy(help_buf, help_buf0, APICLI_MAX_PARM_HELP_LENGTH);
    bcmcli_strncat(help_buf, " - ", APICLI_MAX_PARM_HELP_LENGTH);
    bcmcli_strncat(help_buf, fld->descr ? fld->descr : fld->name, APICLI_MAX_PARM_HELP_LENGTH);
}

/* Allocate CLI parameter array. Set up parm->data */
static bcmcli_cmd_parm *_api_cli_parm_alloc(int nparms)
{
    uint32_t size;
    bcmcli_cmd_parm *parms;
    apicli_parm_data *parm_data;
    int i;

    /* Allocate parameter table and populate it */
    size = (sizeof(bcmcli_cmd_parm) + sizeof(apicli_parm_data)) * (nparms + 1);
    parms = bcmos_calloc(size);
    if (!parms)
        return NULL;

    /* Associate parameter_data structs with parameters */
    parm_data = (apicli_parm_data *)(parms + nparms + 1);
    for (i = 0; i < nparms; i++)
    {
        parms[i].user_data = &parm_data[i];
    }
    return parms;
}

/* clone enum table */
static bcmcli_enum_val *_api_cli_clone_enum_table(bcmcli_cmd_parm *parm)
{
    bcmcli_enum_val *org_table = parm->enum_table;
    bcmcli_enum_val *val = org_table;
    bcmcli_enum_val *clone_table = org_table;
    int i, n;

    BUG_ON(parm->type != BCMCLI_PARM_ENUM);
    while (val && val->name)
    {
        ++val;
    }
    n = val - org_table;

    clone_table = bcmos_calloc(sizeof(bcmcli_enum_val) * (n + 1));
    if (!clone_table)
    {
        return NULL;
    }
    for (i = 0; i < n; i++)
    {
        clone_table[i].name = org_table[i].name;
        clone_table[i].val = org_table[i].val;
    }
    return clone_table;
}


/* populate CLI parameter(s) from a single property. Can be multiple parameters
 * if property contains multiple fields.
 * Returns number of parameters populated >= 0 or error < 0
 */
static int _api_cli_populate_parms_from_property(const bcmcli_prop_descr *pd, const bcmcli_field_descr *fd,
    const bcmcli_field_descr *array_fd, uint32_t offset, uint32_t array_fd_offset, bcmcli_cmd_parm *parms,
    bcmolt_prop_access_id access_level, uint32_t cmd_flags, char *name_buf0, char *help_buf0)
{
    const bcmcli_type_descr *td = fd ? fd->type : pd->type;
    uint32_t nf = 0;
    char name_buf[APICLI_MAX_PARM_NAME_LENGTH];
    char help_buf[APICLI_MAX_PARM_HELP_LENGTH];
    int rc = 0;

    /* At top level take name from property */
    if (td == pd->type)
    {
        /* In case there's a global prefix */
        char *top_name_buf = name_buf0;
        uint32_t top_name_buf_len = APICLI_MAX_PARM_NAME_LENGTH;
        uint32_t prefix_len = strlen(name_buf0);
        if (prefix_len > 0)
        {
            top_name_buf += prefix_len;
            top_name_buf_len -= prefix_len;
        }

        bcmcli_strncpy(top_name_buf, pd->cli_name ? pd->cli_name : pd->name, top_name_buf_len);
        bcmcli_strncpy(help_buf0, pd->descr ? pd->descr : pd->name, APICLI_MAX_PARM_HELP_LENGTH);
    }

    /* For read access we only mark whether read property or not. It is not field-by-field operation */
    if (access_level == BCMOLT_PROP_ACCESS_ID_R)
    {
        td = &bool_type_descr;
    }

    /* In case of arrays we should
     * - check that there is no array in array. It is not supported
     * - store array type descriptor FFU and replace the "current" type descriptor with element type
     * - reset offset because for array fields it should be calculated from array base rather than property
     */
    if (td->base_type == BCMOLT_BASE_TYPE_ID_ARR_DYN || td->base_type == BCMOLT_BASE_TYPE_ID_ARR_FIXED)
    {
        if (array_fd)
        {
            bcmcli_print(current_session, "*** %s in %s: arrays-in-arrays are not supported\n", pd->name, array_fd->name);
            return BCM_ERR_NOT_SUPPORTED;
        }
        /* store array type and fetch element type */
        array_fd = fd ? fd : (const bcmcli_field_descr *)pd;
        if (td->base_type == BCMOLT_BASE_TYPE_ID_ARR_DYN)
        {
            td = td->x.arr_dyn.elem_type;
        }
        else
        {
            td = td->x.arr_fixed.elem_type;
        }
        array_fd_offset = offset;
        offset = 0;
    }

    if (td->base_type == BCMOLT_BASE_TYPE_ID_STRUCT)
    {
        uint16_t f;
        if (!td->x.s.num_fields)
            return 0;
        BUG_ON(!td->x.s.fields);
        for (f = 0; f < td->x.s.num_fields; f++)
        {
            const bcmcli_field_descr *fld = &td->x.s.fields[f];
            _api_cli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
            rc = _api_cli_populate_parms_from_property(pd, fld, array_fd, offset+fld->offset,
                array_fd_offset, &parms[nf], access_level, cmd_flags, name_buf, help_buf);
            if (rc > 0)
                nf +=  rc;
        }
    }
    else if (td->base_type == BCMOLT_BASE_TYPE_ID_UNION)
    {
        /* Union */
        uint16_t f;
        const bcmcli_field_descr *fld;
        bcmcli_cmd_parm *sel_parm;
        apicli_parm_data *sel_data;
        bcmcli_enum_val *e;

        if (!td->x.u.num_common_fields)
            return 0;
        BUG_ON(!td->x.u.common_fields);

        /* Populate parameters preceding the union selector */
        for (f = 0; f < td->x.u.classifier_idx; f++)
        {
            fld = &td->x.u.common_fields[f];
            _api_cli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
            rc =  _api_cli_populate_parms_from_property(pd, fld, array_fd,
                offset+fld->offset, array_fd_offset, &parms[nf], access_level, cmd_flags, name_buf, help_buf);
            if (rc > 0)
                nf += rc;
        }

        /* Now populate parameter for selector */
        sel_parm = &parms[nf];
        fld = &td->x.u.common_fields[f];
        _api_cli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
        rc = _api_cli_populate_parms_from_property(pd, fld, array_fd,
            offset+fld->offset, array_fd_offset, sel_parm, access_level, cmd_flags, name_buf, help_buf);
        if (rc > 0)
            nf += rc;
        /* Clone enum table in order to allow modifying it */
        if (rc >= 1)
        {
            sel_parm->enum_table = _api_cli_clone_enum_table(sel_parm);
            if (!sel_parm->enum_table)
            {
                rc = BCM_ERR_NOMEM;
            }
        }

        /* Now set-up selector */
        sel_parm->flags |= BCMCLI_PARM_FLAG_SELECTOR;
        sel_data = sel_parm->user_data;
        e = sel_parm->enum_table;
        while (e && e->name && rc >= 0)
        {
            fld = &td->x.u.union_fields[e - sel_parm->enum_table];
            if (fld->type)
            {
                int np = _api_cli_get_num_fields_in_type(fld->type);
                int i;

                e->parms = _api_cli_parm_alloc(np);
                if (!e->parms)
                {
                    rc = BCM_ERR_NOMEM;
                    break;
                }
                for (i = 0; i < np; i++)
                {
                    apicli_parm_data *data = e->parms[i].user_data;
                    data->group = sel_data->group;
                }
                /* Collapse substructure name */
                if (fld->type->base_type == BCMOLT_BASE_TYPE_ID_STRUCT ||
                    fld->type->base_type == BCMOLT_BASE_TYPE_ID_UNION)
                {
                    bcmcli_strncpy(name_buf, name_buf0, sizeof(name_buf));
                    bcmcli_strncpy(help_buf, help_buf0, sizeof(help_buf));
                }
                else
                {
                    _api_cli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
                }
                rc = _api_cli_populate_parms_from_property(pd, fld, array_fd,
                    offset+fld->offset, array_fd_offset, e->parms, access_level, cmd_flags, name_buf, help_buf);
            }
            ++e;
        }

        /* Finally populate parameters following the selector parameter */
        for (f = td->x.u.classifier_idx + 1; f < td->x.u.num_common_fields && rc >= 0; f++)
        {
            fld = &td->x.u.common_fields[f];
            _api_cli_populate_name_help(fld, name_buf0, help_buf0, name_buf, help_buf);
            rc = _api_cli_populate_parms_from_property(pd, fld, array_fd,
                offset+fld->offset, array_fd_offset, &parms[nf], access_level, cmd_flags, name_buf, help_buf);
            if (rc > 0)
                nf += rc;
        }
    }
    else
    {
        /* Finally! Simple type that maps to a single CLI parameter */
        nf = _api_cli_populate_parm1(pd, fd, td, array_fd, offset, array_fd_offset,
            &parms[0], cmd_flags, name_buf0, help_buf0);
    }
    return (rc >= 0) ? nf : rc;
}

/* populate CLI parameter table */
static int _api_cli_populate_parms(
    bcmolt_obj_id o,
    bcmolt_mgt_group group,
    uint16_t subgroup,
    bcmolt_prop_access_id access_level,
    bcmcli_cmd_parm *parms,
    uint32_t cmd_flags,
    const char *prefix)
{
    int nf = 0;
    int i;
    bcmos_errno rc = BCM_ERR_OK;

    for (i = 0; rc != BCM_ERR_RANGE; i++)
    {
        const bcmcli_prop_descr *pd;
        char name_buf[APICLI_MAX_PARM_NAME_LENGTH] = "";
        char help_buf[APICLI_MAX_PARM_HELP_LENGTH] = "";

        strncpy(name_buf, prefix, APICLI_MAX_PARM_NAME_LENGTH-1);
        name_buf[APICLI_MAX_PARM_NAME_LENGTH-1] = 0;

        rc = api_cli_object_property(o, group, subgroup, i, &pd);
        if (rc == BCM_ERR_OK && (pd->access & access_level))
        {
            rc = _api_cli_populate_parms_from_property(pd, NULL, NULL, 0, 0, &parms[nf],
                access_level, cmd_flags, name_buf, help_buf);
            if (rc > 0)
                nf += rc;
        }
    }
    return nf;
}


/* compact selector table. squeeze out values that don't have parameter table attached */
static void _api_cli_compact_selector(bcmcli_enum_val *selector, int size)
{
    int i, j;

    for (i = 0; i < size; i++)
    {
        if (!selector[i].parms)
        {
            for ( j = i + 1; j < size && !selector[j].parms; j ++)
                ;
            if (j < size)
            {
                memcpy(&selector[i], &selector[j], sizeof(bcmcli_enum_val));
                memset(&selector[j], 0, sizeof(bcmcli_enum_val));
            }
            else
            {
                memset(&selector[i], 0, sizeof(bcmcli_enum_val));
            }
        }
    }
}

/* Free CLI parameters. both name and description are allocated dynamically */
static void _api_cli_free_parms(bcmcli_cmd_parm *parms)
{
    bcmcli_cmd_parm *p = parms;

    while (p->name)
    {
        if ((p->flags & BCMCLI_PARM_FLAG_SELECTOR))
        {
            /* Remove selector table */
            bcmcli_enum_val *sel = p->enum_table;
            if (sel)
            {
                bcmcli_enum_val *e = sel;
                while(e->name)
                {
                    if (e->parms)
                    {
                        _api_cli_free_parms(e->parms);
                    }
                    ++e;
                }
                bcmos_free(sel);
            }
        }
        if (p->description)
            bcmos_free(APICLI_CAST_DISCARD_CONST(p->description, void *));
        if (p->name)
            bcmos_free(APICLI_CAST_DISCARD_CONST(p->name, void *));
        if (p->max_array_size && p->values)
            bcmos_free(p->values);
        if (p->value.buffer.start)
            bcmolt_buf_free(&p->value.buffer);

        ++p;
    }
    bcmos_free(parms);
}

static uint8_t _apicli_get_num_cmd_parms(bcmolt_mgt_group group, api_cli_flags flags)
{
    if (group == BCMOLT_MGT_GROUP_STAT)
        return 2; /* object + stat ID */
    else if (group == BCMOLT_MGT_GROUP_CFG && (flags & API_CLI_FLAGS_MULTI) != API_CLI_FLAGS_NONE)
        return 3; /* object + max msgs + invert flag */
    else
        return 1; /* object */
}

/* Read generated info and add CLI command */
static bcmos_errno _api_cli_add(bcmcli_entry *dir, const char *cmd_name, const char *cmd_descr,
    bcmolt_mgt_group group, bcmolt_prop_access_id access_level, bcmcli_cmd_cb cmd_handler, api_cli_flags flags)
{
    bcmcli_cmd_extra_parm cmd_extras = { .free_parms = _api_cli_free_parms };
    bcmcli_cmd_parm *cmd_parms;
    bcmcli_enum_val *obj_selector;
    bcmolt_obj_id o;
    bcmos_errno rc = BCM_ERR_OK;
    uint32_t cmd_flags = 0;
    uint8_t num_cmd_parms = _apicli_get_num_cmd_parms(group, flags);
    int n_obj;
    int i;

    /* Command flags: parameters in the following groups are optional */
    if (group == BCMOLT_MGT_GROUP_CFG || group == BCMOLT_MGT_GROUP_STAT || group == BCMOLT_MGT_GROUP_AUTO_CFG)
        cmd_flags = BCMCLI_PARM_FLAG_OPTIONAL;

    /* command parameters are:
     * - object_name (selector)
     * - object_key_fields
     * - object_per_group_fields filtered by access
     * Therefore, there is 1 top-level enum parameter (object type) with per-value parameter tables
     * In the case of operations or proxy messages, there is also a top-level enum parameter for the oper/proxy name
     */

    /* Allocate enum table based on max number of objects. Will be compacted in the end */
    cmd_parms = bcmos_calloc(sizeof(bcmcli_cmd_parm) * (num_cmd_parms + 1));
    if (!cmd_parms)
        return BCM_ERR_NOMEM;

    /* Allocate enough space for all object entries as well as a terminator entry (which is left NULL) */
    obj_selector = bcmos_calloc(sizeof(bcmcli_enum_val) * (BCMOLT_OBJ_ID__NUM_OF + 1));
    if (!obj_selector)
        goto nomem_cleanup;

    /* Allocate parameter table */
    n_obj = 0;
    for (o = 0; o < BCMOLT_OBJ_ID__NUM_OF; o++)
    {
        uint32_t nkeyfields = 0;
        uint32_t nfields = 0;
        uint32_t nfilterfields = 0;
        uint32_t size;
        uint16_t s;
        uint16_t subgroup_count = api_cli_get_subgroup_count(o, group);
        bcmcli_enum_val *sub_selector;

        if (!bcmolt_object_is_supported(current_system_mode, o) && o != BCMOLT_OBJ_ID_DEVICE)
            continue;

        if (subgroup_count == 0)
            continue;

        obj_selector[n_obj].val = o;
        rc = api_cli_object_name(o, &obj_selector[n_obj].name, NULL);
        if (rc)
            continue;

        /* Get number of key fields and save it */
        if (group == BCMOLT_MGT_GROUP_AUTO_CFG)
        {
            nkeyfields = 0;
        }
        else
        {
            _api_cli_get_num_fields_in_group(o, BCMOLT_MGT_GROUP_KEY, 0, BCMOLT_PROP_ACCESS_ID_W, &nkeyfields);
        }

        /* Allocate subgroup enum table */
        sub_selector = bcmos_calloc(sizeof(bcmcli_enum_val) * (subgroup_count + 1));
        if (!sub_selector)
            goto nomem_cleanup;

        /* Allocate single subgroup command parameter */
        size = sizeof(bcmcli_cmd_parm) * 2;
        obj_selector[n_obj].parms = bcmos_calloc(size);
        if (!obj_selector[n_obj].parms)
        {
            bcmos_free(sub_selector);
            goto nomem_cleanup;
        }

        /* Setup single subgroup command parameter */
        obj_selector[n_obj].parms[0].type = BCMCLI_PARM_ENUM;
        obj_selector[n_obj].parms[0].flags = BCMCLI_PARM_FLAG_SELECTOR;
        obj_selector[n_obj].parms[0].enum_table = sub_selector;
        rc = _api_cli_copy_parm_name(&obj_selector[n_obj].parms[0],
                                 "sub",
                                 "Subgroup (specific operation / proxy msg)");
        if (rc)
            goto nomem_cleanup;

        for (s = 0; s < subgroup_count; ++s)
        {
            const char *sub_name;
            bcmcli_cmd_parm *parm_ptr;

            /* Get name of specific subgroup */
            rc = api_cli_object_subgroup_name(o, group, s, &sub_name, NULL);
            if (rc)
                continue;

            /* Setup entry in subgroup enum table */
            sub_selector[s].name = sub_name;
            sub_selector[s].val = s;

            /* Get number of group fields */
            rc = _api_cli_get_num_fields_in_group(o, group, s, access_level, &nfields);
            if (rc)
                continue;

            /* For multi-object GET messages, populate the filter fields just like a SET (except that all read-only
               fields are also settable) */
            if ((flags & API_CLI_FLAGS_MULTI) != API_CLI_FLAGS_NONE)
            {
                rc = _api_cli_get_num_fields_in_group(o, group, s, BCMOLT_PROP_ACCESS_ID_RW, &nfilterfields);
                if (rc)
                    continue;
            }


            if ((flags & API_CLI_FLAGS_IGNORE_FIELDS) != API_CLI_FLAGS_NONE)
            {
                nfilterfields = 0;
                nfields = 0;
            }


            /* Allocate parameter table and populate it */
            sub_selector[s].parms = _api_cli_parm_alloc(nfields + nkeyfields + nfilterfields);
            if (!sub_selector[s].parms)
            {
                rc = BCM_ERR_NOMEM;
                goto nomem_cleanup;
            }
            for (i = 0; i < nkeyfields + nfields + nfilterfields; i++)
            {
                apicli_parm_data *parm_data = sub_selector[s].parms[i].user_data;
                parm_data->group = (i < nkeyfields) ? BCMOLT_MGT_GROUP_KEY : group;
            }

            parm_ptr = sub_selector[s].parms;
            if (nkeyfields)
            {
                rc = _api_cli_populate_parms(o, BCMOLT_MGT_GROUP_KEY, 0, BCMOLT_PROP_ACCESS_ID_W, parm_ptr, 0, "");
                if (rc < 0)
                    goto nomem_cleanup;
                parm_ptr += rc;
            }
            if (nfilterfields)
            {
                rc = _api_cli_populate_parms(o, group, s, BCMOLT_PROP_ACCESS_ID_RW, parm_ptr, cmd_flags, "filter.");
                if (rc < 0)
                    goto nomem_cleanup;
                parm_ptr += rc;
            }
            if (nfields)
            {
                rc = _api_cli_populate_parms(o, group, s, access_level, parm_ptr, cmd_flags, "");
                if (rc < 0)
                    goto nomem_cleanup;
                parm_ptr += rc;
            }
        }

        /* Compact sub_selector enum. Removes holes (values without parameter table) */
        _api_cli_compact_selector(sub_selector, subgroup_count);

        /* If the group type doesn't support subgroups, remove the subgroup param entry */
        if (group == BCMOLT_MGT_GROUP_CFG || group == BCMOLT_MGT_GROUP_STAT || group == BCMOLT_MGT_GROUP_AUTO_CFG)
        {
            /* Free the memory associated with the (single) subgroup param */
            bcmos_free(APICLI_CAST_DISCARD_CONST(obj_selector[n_obj].parms[0].name, void *));
            bcmos_free(APICLI_CAST_DISCARD_CONST(obj_selector[n_obj].parms[0].description, void *));
            bcmos_free(obj_selector[n_obj].parms);
            /* Assign the subgroup params to the root object params */
            obj_selector[n_obj].parms = sub_selector[0].parms;
            bcmos_free(sub_selector);
        }

        ++n_obj; /* number of configured objects */
    }

    /* Compact obj_selector enum. Removes holes (values without parameter table) */
    _api_cli_compact_selector(obj_selector, BCMOLT_OBJ_ID__NUM_OF);

    /* Add a 'clear on read' to stats group */
    if (group == BCMOLT_MGT_GROUP_STAT)
    {
        cmd_parms[0].type = BCMCLI_PARM_ENUM;
        cmd_parms[0].enum_table = bool_enum;
        rc = _api_cli_copy_parm_name(&cmd_parms[0], "clear", "clear on read");
        if (rc)
            goto nomem_cleanup;
    }

    /* Add 'max number of messages to read' and 'invert filter' to cfg get_multi msgs */
    if (group == BCMOLT_MGT_GROUP_CFG && (flags & API_CLI_FLAGS_MULTI) != API_CLI_FLAGS_NONE)
    {
        cmd_parms[0].type = BCMCLI_PARM_UNUMBER;
        rc = _api_cli_copy_parm_name(&cmd_parms[0], "max_msgs", "max number of API GET messages to receive per call");
        if (rc)
            goto nomem_cleanup;

        cmd_parms[1].type = BCMCLI_PARM_ENUM;
        cmd_parms[1].enum_table = bool_enum;
        rc = _api_cli_copy_parm_name(&cmd_parms[1], "filter_invert", "invert filter (select objects that don't match)");
        if (rc)
            goto nomem_cleanup;
    }

    /* We are ready to add this command */
    cmd_parms[num_cmd_parms - 1].type = BCMCLI_PARM_ENUM;
    cmd_parms[num_cmd_parms - 1].flags = BCMCLI_PARM_FLAG_SELECTOR;
    cmd_parms[num_cmd_parms - 1].enum_table = obj_selector;
    rc = _api_cli_copy_parm_name(&cmd_parms[num_cmd_parms - 1], "object", "Object Type");
    if (rc)
        goto nomem_cleanup;
    rc = bcmcli_cmd_add(dir, cmd_name, cmd_handler, cmd_descr,
        (access_level == BCMOLT_PROP_ACCESS_ID_W) ? BCMCLI_ACCESS_ADMIN : BCMCLI_ACCESS_GUEST,
        &cmd_extras, cmd_parms);
    if (rc)
        goto nomem_cleanup;
    return 0;

nomem_cleanup:
    if (obj_selector)
    {
        for (o = 0; o < BCMOLT_OBJ_ID__NUM_OF; o++)
        {
            if (obj_selector[o].parms)
                _api_cli_free_parms(obj_selector[o].parms);
        }
        bcmos_free(obj_selector);
    }
    bcmos_free(cmd_parms);
    return rc;
}

#ifdef BCM_SUBSYSTEM_HOST

/* Current device change indication */
static void _api_cli_device_change_ind(bcmcli_session *session, bcmolt_devid dev)
{
    api_cli_set_commands(session);
}

#ifdef LINUX_USER_SPACE

static bcmcli_session *_apicli_log;
static FILE *_apicli_log_file;

static int _apicli_log_write_cb(bcmcli_session *session, const char *buf, uint32_t size)
{
    if (_apicli_log_file == NULL || buf == NULL)
        return BCM_ERR_INTERNAL;
    fwrite(buf, 1, size, _apicli_log_file);
    fflush(_apicli_log_file);
    return BCM_ERR_OK;
}

/* Enable/disable API logging
 *       BCMCLI_MAKE_PARM("file", "Log file. Use \"-\" to disable logging", BCMCLI_PARM_STRING, 0));
 */
static bcmos_errno _apicli_log_handler(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    const char *fname = parm[0].value.string;
    bcmcli_session_parm session_params =
    {
        .write = _apicli_log_write_cb,
        .name = "api_log"
    };
    bcmos_errno rc;
    time_t start_time;

    /* Close existing log session if any */
    if (_apicli_log)
    {
        bcmcli_log_set(BCMCLI_LOG_NONE, NULL);
        bcmcli_session_close(_apicli_log);
        fclose(_apicli_log_file);
        _apicli_log = NULL;
        _apicli_log_file = NULL;
    }

    if (!strcmp(fname, "-"))
        return BCM_ERR_OK;

    /* Starting a new log session */
    _apicli_log_file = fopen(fname, "a");
    if (_apicli_log_file == NULL)
    {
        bcmcli_print(session, "Can't open file %s for logging\n", fname);
        return BCM_ERR_PARM;
    }
    rc = bcmcli_session_open_user(&session_params, &_apicli_log);
    if (rc)
    {
        fclose(_apicli_log_file);
        _apicli_log_file = NULL;
        bcmcli_print(session, "Can't open log session. Error %s\n", bcmos_strerror(rc));
        return rc;
    }
    time(&start_time);
    bcmcli_log_set(BCMCLI_LOG_C_COMMENT, _apicli_log);
    bcmcli_log("/* API logging session started. %s */\n", ctime(&start_time));
    return BCM_ERR_OK;
}
#endif /* #ifdef LINUX_USER_SPACE */

#endif /* #ifdef BCM_SUBSYSTEM_HOST */

static void api_cli_find_del_cmd(bcmcli_entry *dir, const char *cmd_name)
{
    bcmcli_entry *cmd;
    cmd = bcmcli_cmd_find(dir, cmd_name);
    if (cmd)
    {
        bcmcli_token_destroy(cmd);
    }
}

/* Unregisters commands and directories */
static void api_cli_del_commands(bcmcli_session *session)
{
    bcmcli_entry *dir;

    dir = bcmcli_dir_find(api_parent_dir, "api");
    if (!dir)
    {
        return;
    }
    api_cli_find_del_cmd(dir, "set");
    api_cli_find_del_cmd(dir, "get");
    api_cli_find_del_cmd(dir, "multiget");
    api_cli_find_del_cmd(dir, "clear");
    api_cli_find_del_cmd(dir, "modify");
    api_cli_find_del_cmd(dir, "stat");
    api_cli_find_del_cmd(dir, "oper");
    api_cli_find_del_cmd(dir, "send");
    api_cli_find_del_cmd(dir, "saset");
    api_cli_find_del_cmd(dir, "saget");
    api_cli_find_del_cmd(dir, "acset");
    api_cli_find_del_cmd(dir, "acget");
    api_cli_find_del_cmd(dir, "objects");
#ifdef BCM_SUBSYSTEM_HOST
    api_cli_find_del_cmd(dir, "log");
#endif
}

/* Registers commands and directories */
static bcmos_errno api_cli_add_commands(bcmcli_session *session)
{
    bcmcli_entry *api_dir;
    bcmos_errno rc;

    if ((api_dir = bcmcli_dir_find(api_parent_dir, "api")) == NULL)
    {
        api_dir = bcmcli_dir_add(api_parent_dir, "api", "Maple API", BCMCLI_ACCESS_GUEST, NULL);
        if (api_dir == NULL)
        {
            bcmcli_session_print(session, "Can't create api directory\n");
            return BCM_ERR_INTERNAL;
        }
    }

    current_session = session;
    bcmolt_system_mode_get(current_device, &current_system_mode);

    /* Now generate and add commands */
    rc = _api_cli_add(api_dir, "set", "Set object configuration", BCMOLT_MGT_GROUP_CFG,
        BCMOLT_PROP_ACCESS_ID_W, _apicli_set_handler, API_CLI_FLAGS_NONE);
    rc = rc ? rc : _api_cli_add(api_dir, "get", "Get object configuration", BCMOLT_MGT_GROUP_CFG,
        BCMOLT_PROP_ACCESS_ID_R, _apicli_get_handler, API_CLI_FLAGS_NONE);
    rc = rc ? rc : _api_cli_add(api_dir, "clear", "Clear object configuration", BCMOLT_MGT_GROUP_CFG,
        BCMOLT_PROP_ACCESS_ID_R, _apicli_clear_handler, API_CLI_FLAGS_IGNORE_FIELDS);
    rc = rc ? rc : _api_cli_add(api_dir, "stat", "Get statistics", BCMOLT_MGT_GROUP_STAT, BCMOLT_PROP_ACCESS_ID_R,
        _apicli_stat_handler, API_CLI_FLAGS_NONE);
    rc = rc ? rc : _api_cli_add(api_dir, "oper", "Initiate Operation", BCMOLT_MGT_GROUP_OPER,
        BCMOLT_PROP_ACCESS_ID_W, _apicli_oper_handler, API_CLI_FLAGS_NONE);
    rc = rc ? rc : _api_cli_add(api_dir, "send", "Send message to ONU", BCMOLT_MGT_GROUP_PROXY,
        BCMOLT_PROP_ACCESS_ID_W, _apicli_send_handler, API_CLI_FLAGS_NONE);
    rc = rc ? rc : _api_cli_add(api_dir, "saset", "Set statistic alarm configuration",
        BCMOLT_MGT_GROUP_STAT_CFG, BCMOLT_PROP_ACCESS_ID_W, _apicli_stat_cfg_set_handler, API_CLI_FLAGS_NONE);
    rc = rc ? rc : _api_cli_add(api_dir, "saget", "Get statistic alarm configuration",
        BCMOLT_MGT_GROUP_STAT_CFG, BCMOLT_PROP_ACCESS_ID_R, _apicli_stat_cfg_get_handler, API_CLI_FLAGS_IGNORE_FIELDS);
    rc = rc ? rc : _api_cli_add(api_dir, "acset", "Set autonomous message configuration",
        BCMOLT_MGT_GROUP_AUTO_CFG, BCMOLT_PROP_ACCESS_ID_W, _apicli_auto_cfg_set_handler, API_CLI_FLAGS_NONE);
    rc = rc ? rc : _api_cli_add(api_dir, "acget", "Get autonomous message configuration",
        BCMOLT_MGT_GROUP_AUTO_CFG, BCMOLT_PROP_ACCESS_ID_R, _apicli_auto_cfg_get_handler, API_CLI_FLAGS_NONE);
    rc = rc ? rc : _api_cli_add(api_dir, "multiget", "Get configuration for multiple objects",
        BCMOLT_MGT_GROUP_CFG, BCMOLT_PROP_ACCESS_ID_R, _apicli_auto_cfg_get_multi_handler, API_CLI_FLAGS_MULTI);

    /* List all system objects */
    rc = rc ? rc : bcmcli_cmd_add(api_dir, "objects", _apicli_objects_handler,
        "Object Types", BCMCLI_ACCESS_GUEST, NULL, NULL);

#if defined(BCM_SUBSYSTEM_HOST) && defined(LINUX_USER_SPACE)
    BCMCLI_MAKE_CMD(api_dir, "log", "Log API calls", _apicli_log_handler,
        BCMCLI_MAKE_PARM("file", "Log file. Use \"-\" to disable logging", BCMCLI_PARM_STRING, 0));
#endif

    return rc;
}

/* Update API CLI commands for the current device */
bcmos_errno api_cli_set_commands(bcmcli_session *session)
{
    bcmos_errno rc;
    api_cli_del_commands(session);
    rc = api_cli_add_commands(session);
    return rc;
}

/* Init API CLI commands for the current device */
bcmos_errno api_cli_init(bcmcli_entry *parent_dir, bcmcli_session *session)
{
    bcmos_errno rc;

    api_parent_dir = parent_dir;

    rc = api_cli_set_commands(session);

#ifdef BCM_SUBSYSTEM_HOST
    /* Subscribe for device change indication */
    rc = rc ? rc : bcmolt_dev_sel_ind_register(_api_cli_device_change_ind);
#endif

    return rc;
}
