/*
<: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 <bcmtr_debug.h>
#include <bcmtr_debug_cli.h>
#include <bcm_api_cli_helpers.h>
#ifdef BCM_SUBSYSTEM_HOST
#include <bcmolt_dev_selector.h>
#endif

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

static bcmcli_entry *cld_cli_dir;

static bcmos_errno _bcmtr_cld_cli_create(void);
static void _bcmtr_cld_cli_destroy(void);

/*
 * CLI handlers
 */

static bcmos_errno _bcmtr_cld_cli_setget_level(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    bcmcli_number obj = bcmcli_parm_get(session, "object")->value.number;
    bcmcli_cmd_parm *grp_parm = bcmcli_parm_get(session, "group");
    bcmcli_number group = grp_parm ? grp_parm->value.number : -1;
    bcmcli_cmd_parm *subgrp_parm = bcmcli_parm_get(session, "subgroup");
    bcmcli_number subgroup = subgrp_parm ? subgrp_parm->value.number : -1;
    bcmtr_cld_type level = bcmcli_parm_get(session, "level")->value.number;
    bcmtr_cld_filter filter = {};
    bcmos_errno rc;

    if (obj == -1 || !bcmcli_parm_is_set(session, bcmcli_parm_get(session, "object")))
    {
        filter.object = BCMOLT_OBJECT_ANY;
    }
    else
    {
        filter.object = obj;
    }

    if (group == -1 || !grp_parm || !bcmcli_parm_is_set(session, grp_parm))
    {
        filter.group = BCMOLT_MGT_GROUP_ANY;
    }
    else
    {
        filter.group = group;
    }

    if (subgroup == -1 || !subgrp_parm || !bcmcli_parm_is_set(session, subgrp_parm))
    {
        filter.subgroup = BCMOLT_SUBGROUP_ANY;
    }
    else
    {
        filter.subgroup = subgroup;
    }

    /* Get or set level ? */
    if (bcmcli_parm_is_set(session, bcmcli_parm_get(session, "level")))
    {
        rc = bcmtr_cld_level_set(current_device, &filter, level);
    }
    else
    {
        rc = bcmtr_cld_level_get(current_device, &filter, &level);
        if (rc == BCM_ERR_OK)
        {
            bcmcli_session_print(session, "capture:%s log:%s dump:%s\n",
                (level & BCMTR_CLD_CAPTURE) ? "on" : "off",
                (level & BCMTR_CLD_LOG) ? "on" : "off",
                ((level & BCMTR_CLD_DUMP) == BCMTR_CLD_DUMP) ? "all" :
                    (level & BCMTR_CLD_DUMP_HDR) ? "headers" : "off");
        }
    }

    return rc;
}

static bcmos_errno _bcmtr_cld_cli_capture_init(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    bcmcli_number size = bcmcli_parm_get(session, "size")->value.number;
    bcmos_bool stop_on_full = bcmcli_parm_get(session, "stop_on_full")->value.number;
    bcmos_bool autostart = bcmcli_parm_get(session, "autostart")->value.number;
    bcmtr_capture_parm p = {};

    p.size = size;
    p.stop_on_full = stop_on_full;
    p.activate = autostart;

    return bcmtr_capture_init(current_device, &p);
}

static bcmos_errno _bcmtr_cld_cli_capture_delete(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    bcmtr_capture_destroy(current_device);
    return BCM_ERR_OK;
}

static bcmos_errno _bcmtr_cld_cli_capture_start(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmtr_capture_start_stop(current_device, BCMOS_TRUE);
}

static bcmos_errno _bcmtr_cld_cli_capture_stop(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    return bcmtr_capture_start_stop(current_device, BCMOS_FALSE);
}

static bcmos_errno _bcmtr_cld_cli_capture_dump(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    uint32_t nmsgs;
    bcmos_errno rc;

    rc = bcmtr_capture_dump(session, current_device, &nmsgs);
    if (!rc)
    {
        bcmcli_session_print(session, "Dumped %u messages\n", nmsgs);
    }

    return BCM_ERR_OK;
}

static bcmos_errno _bcmtr_cld_cli_capture_info(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t nparms)
{
    bcmtr_capture_info info;
    bcmos_errno rc;

    rc = bcmtr_capture_info_get(current_device, &info);
    if (!rc)
    {
        bcmcli_session_print(session, "Buffer: size=%u used=%u. Events: recorded=%u lost=%d. Wraps around:%u\n",
            info.size, info.used, info.msgs, info.lost, info.wa);
    }

    return BCM_ERR_OK;
}


#ifdef BCM_SUBSYSTEM_HOST
/* Current device change indication */
static void _bcmtr_cld_device_change_ind(bcmcli_session *session, bcmolt_devid dev)
{
    bcmcli_entry *cur_dir = bcmcli_dir_get(session);
    bcmos_bool is_cld_cur_dir = (cur_dir && cur_dir == cld_cli_dir);
    bcmos_errno rc;

    /* Destroy and re-create CLD CLI directory */
    _bcmtr_cld_cli_destroy();
    rc = _bcmtr_cld_cli_create();

    /* Restore current CLI directory to CLD */
    if (!rc && is_cld_cur_dir)
        bcmcli_dir_set(session, cld_cli_dir);
}
#endif

/* allocate memory for name and description and copy to to parm */
static bcmos_errno _bcmtr_cld_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(BCMTR_CLD_CAST_DISCARD_CONST(parm->name, void *), name);
    strcpy(BCMTR_CLD_CAST_DISCARD_CONST(parm->description, void *), descr);
    return BCM_ERR_OK;
}

/* Free "level" command parameters. both name and description are allocated dynamically */
static void _bcmtr_cld_free_level_parms(bcmcli_cmd_parm *parms)
{
    bcmcli_cmd_parm *p = parms;

    while (p->name)
    {
        if (p->type == BCMCLI_PARM_ENUM && p->enum_table)
        {
            if ((p->flags & BCMCLI_PARM_FLAG_SELECTOR))
            {
                bcmcli_enum_val *e = p->enum_table;
                while(e->name)
                {
                    if (e->parms)
                    {
                        _bcmtr_cld_free_level_parms(e->parms);
                    }
                    ++e;
                }
            }
            bcmos_free(p->enum_table);
        }
        if (p->description)
            bcmos_free(BCMTR_CLD_CAST_DISCARD_CONST(p->description, void *));
        if (p->name)
            bcmos_free(BCMTR_CLD_CAST_DISCARD_CONST(p->name, void *));

        ++p;
    }
    bcmos_free(parms);
}

/* Add "level" command */
static bcmos_errno _bcmtr_cld_add_level_cmd(bcmcli_entry *dir)
{
    /* object:            *all, object list
     * group:   selector: *all, group list
     * subgroup:          *all, subgroup list
     * level:   bitmask
     */
    bcmcli_cmd_extra_parm cmd_extras = { .free_parms = _bcmtr_cld_free_level_parms };
    bcmcli_enum_val *obj_selector;
    bcmcli_cmd_parm *cmd_parms;
    static const char *all_name = "*all";
    bcmolt_system_mode current_system_mode;
    int n_obj = 0;
    bcmolt_obj_id o;
    bcmos_errno rc = BCM_ERR_NOMEM;

    /* Allocate top level parameters: object selector, level, terminator */
    cmd_parms = bcmos_calloc(sizeof(bcmcli_cmd_parm) * 3);
    if (!cmd_parms)
    {
        return BCM_ERR_NOMEM;
    }

    /* Allocate object enum table. 2 extra entries for *all and terminator */
    obj_selector = bcmos_calloc(sizeof(bcmcli_enum_val) * (BCMOLT_OBJ_ID__NUM_OF + 2));
    if (!obj_selector)
    {
        goto cleanup;
    }

    /* Fill up parameters */
    rc = _bcmtr_cld_copy_parm_name(&cmd_parms[0], "object", "Object Name");
    cmd_parms[0].type = BCMCLI_PARM_ENUM;
    cmd_parms[0].flags = BCMCLI_PARM_FLAG_SELECTOR;
    cmd_parms[0].enum_table = obj_selector;

    rc = rc ? rc : _bcmtr_cld_copy_parm_name(&cmd_parms[1], "level", "Level bitmask: 1=capture,2=log,4=print hdr,8=print body");
    cmd_parms[1].type = BCMCLI_PARM_DECIMAL;
    cmd_parms[1].flags = BCMCLI_PARM_FLAG_OPTIONAL;

    /* obj_selector[0] is reserved for *all */
    obj_selector[0].name = all_name;
    obj_selector[0].val = -1;

    /* Go over objects */
    bcmolt_system_mode_get(current_device, &current_system_mode);
    for (o = 0; o < BCMOLT_OBJ_ID__NUM_OF; o++)
    {
        bcmcli_enum_val *grp_selector;
        bcmcli_cmd_parm *grp_parm;
        bcmolt_mgt_group g;
        int n_grp = 0;

        if (!bcmolt_object_is_supported(current_system_mode, o))
            continue;

        /* Allocate group parameter and selector */
        ++n_obj;
        obj_selector[n_obj].val = o;
        rc = api_cli_object_name(o, &obj_selector[n_obj].name, NULL);
        if (rc != BCM_ERR_OK)
            goto cleanup;

        obj_selector[n_obj].parms = grp_parm = bcmos_calloc(sizeof(bcmcli_cmd_parm)*2);
        if (!grp_parm)
            goto cleanup;
        rc = _bcmtr_cld_copy_parm_name(grp_parm, "group", "Message group");
        grp_parm->type = BCMCLI_PARM_ENUM;
        grp_parm->flags = BCMCLI_PARM_FLAG_SELECTOR;
        grp_parm->enum_table = grp_selector = bcmos_calloc(sizeof(bcmcli_enum_val) * (BCMOLT_MGT_GROUP__NUM_OF + 1));
        if (!grp_selector)
            goto cleanup;

        /* Selector 0 is reserved for *all */
        grp_selector[0].name = all_name;
        grp_selector[0].val = -1;

        /* Go over groups */
        for (g = 1; g < BCMOLT_MGT_GROUP__NUM_OF; g++)
        {
            uint16_t subgroup_count = api_cli_get_subgroup_count(o, g);
            bcmcli_enum_val *subgrp_table;
            bcmcli_cmd_parm *subgrp_parm;
            uint16_t s;
            int sg_table_idx;

            if (subgroup_count == 0)
                continue;

            ++n_grp;
            grp_selector[n_grp].name = apicli_mgt_group_to_str(g);
            grp_selector[n_grp].val = g;

            /* Skip subgroup selector for groups that don't support it */
            if (g != BCMOLT_MGT_GROUP_AUTO      &&
                g != BCMOLT_MGT_GROUP_OPER      &&
                g != BCMOLT_MGT_GROUP_PROXY     &&
                g != BCMOLT_MGT_GROUP_PROXY_RX)
            {
                continue;
            }

            grp_selector[n_grp].parms = subgrp_parm = bcmos_calloc(sizeof(bcmcli_cmd_parm)*2);
            if (!subgrp_parm)
                goto cleanup;
            rc = rc ? rc : _bcmtr_cld_copy_parm_name(subgrp_parm, "subgroup", "Message sub-group");
            subgrp_parm->type = BCMCLI_PARM_ENUM;
            subgrp_parm->enum_table = subgrp_table = bcmos_calloc(sizeof(bcmcli_enum_val) * (subgroup_count + 2));
            if (!subgrp_table)
                goto cleanup;
            subgrp_table[0].name = all_name;
            subgrp_table[0].val = -1;

            sg_table_idx = 1;
            for (s = 0; s < subgroup_count; s++)
            {
                if (api_cli_object_subgroup_name(o, g, s, &subgrp_table[sg_table_idx].name, NULL) == BCM_ERR_OK)
                {
                    subgrp_table[sg_table_idx].val = s;
                    ++sg_table_idx;
                }
            }
        }
    }

    /* Finally add command */
    rc = bcmcli_cmd_add(dir, "level", _bcmtr_cld_cli_setget_level, "Set/get cld level", BCMCLI_ACCESS_ADMIN,
        &cmd_extras, cmd_parms);
    if (rc)
        goto cleanup;
    return BCM_ERR_OK;

cleanup:
    _bcmtr_cld_free_level_parms(cmd_parms);
    return rc;
}

/* Create CLI commands */
static bcmos_errno _bcmtr_cld_cli_create(void)
{
    bcmcli_entry *dir;
    bcmos_errno err;

    dir = bcmcli_dir_add(NULL, "cld", "Transport Capture, Log, Debug", BCMCLI_ACCESS_ADMIN, NULL);
    BCMOS_CHECK_RETURN_ERROR(dir == NULL, BCM_ERR_NOMEM);

    err = _bcmtr_cld_add_level_cmd(dir);
    if (err)
        return err;

    BCMCLI_MAKE_CMD(dir, "init", "Initialize capture buffer", _bcmtr_cld_cli_capture_init,
        BCMCLI_MAKE_PARM("size", "Buffer size (bytes)", BCMCLI_PARM_UDECIMAL, 0),
        BCMCLI_MAKE_PARM_ENUM("stop_on_full", "Stop capture when buffer is full (yes) or wrap-around (no)",
            bcmcli_enum_bool_table, 0),
        BCMCLI_MAKE_PARM_ENUM("autostart", "Autostart", bcmcli_enum_bool_table, 0) );

    BCMCLI_MAKE_CMD_NOPARM(dir, "delete", "Destroy buffer", _bcmtr_cld_cli_capture_delete);

    BCMCLI_MAKE_CMD_NOPARM(dir, "start", "Start capture", _bcmtr_cld_cli_capture_start);

    BCMCLI_MAKE_CMD_NOPARM(dir, "stop", "Stop capture", _bcmtr_cld_cli_capture_stop);

    BCMCLI_MAKE_CMD_NOPARM(dir, "dump", "Dump capture buffer", _bcmtr_cld_cli_capture_dump);

    BCMCLI_MAKE_CMD_NOPARM(dir, "info", "Capture info", _bcmtr_cld_cli_capture_info);

    cld_cli_dir = dir;

    return BCM_ERR_OK;

}

/* Destroy CLI commands */
static void _bcmtr_cld_cli_destroy(void)
{
    if (cld_cli_dir)
    {
        bcmcli_token_destroy(cld_cli_dir);
        cld_cli_dir = NULL;
    }
}


/** Initialize CLD CLI commands
 * \returns BCM_ERR_OK (0) if successful
 */
bcmos_errno bcmtr_cld_cli_init(void)
{
    bcmos_errno err = BCM_ERR_OK;

#ifdef BCM_SUBSYSTEM_HOST
    /* Subscribe for device change indication */
    err = bcmolt_dev_sel_ind_register(_bcmtr_cld_device_change_ind);
#endif

    err = err ? err : _bcmtr_cld_cli_create();

    return err;
}

/** Clean-up CLD CLI commands */
void bcmtr_cld_cli_exit(void)
{
    _bcmtr_cld_cli_destroy();
}
