/*
  <: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 "bcm_dev_log.h"
#include "bcmolt_api.h"
#include "bcm_api_cli_helpers.h"
#include "bcmolt_model_types.h"
#include "bcmtr_debug.h"
#include "bcmtr_interface.h"
#include "bcmolt_user_appl_playback.h"
#include "bcmolt_bit_utils.h"

/* 'MPBx' in ASCII (M)aple (P)lay(b)ack version x */
#define VERSION0    0x4d504230
#define VERSION1    0x4d504231

static const uint32_t CHUNK_SIZE = 2000;

static const char *cap_loc_str[BCMOLT_API_CAPTURE_LOCATION__NUM_OF] =
{
    "device",
    "host"
};

typedef struct
{
    dev_log_id log_id;
} playback_context;

static playback_context pb_ctxt[BCMTR_MAX_OLTS];

typedef enum
{
    PB_FORMAT_API_CLI,
    PB_FORMAT_C_API,

    PB_FORMAT__COUNT
} pb_format;

typedef enum
{
    PB_CLI_EXTRA_NONE,
    PB_CLI_EXTRA_MULTI,
    PB_CLI_EXTRA_STAT,
    PB_CLI_EXTRA_SUBGROUP
} pb_cli_extra;

typedef enum
{
    PB_FIELDS_NONE,
    PB_FIELDS_GET,
    PB_FIELDS_MULTI,
    PB_FIELDS_SET
} pb_fields;

typedef struct
{
    uint32_t version;
    bcmolt_api_capture_location location;
    bcmolt_firmware_sw_version fw_ver;
    bcmolt_host_sw_version host_ver;
    uint32_t buf_size;
    void *capture_buffer;
} bcmolt_playback;

typedef struct
{
    bcmolt_buf buf;
    bcmtr_capture_entry hdr;
    uint8_t *msg_start;
} playback_iterator_raw;

typedef struct
{
    playback_iterator_raw raw;
    bcmolt_buf msg_buf;
    bcmolt_msg *msg;
    bcmos_errno err;
} playback_iterator;

#define FOR_EACH_CAPTURE_ENTRY(it, buffer, size) \
    bcmolt_buf_init(&(it).buf, size, buffer, BCMOLT_BUF_ENDIAN_FIXED); \
    while (bcmtr_capture_entry_get_next(&(it).buf, &(it).hdr, &(it).msg_start))

#define FOR_EACH_PLAYBACK_MSG(it, buffer, size) \
    bcmolt_buf_init(&(it).raw.buf, size, buffer, BCMOLT_BUF_ENDIAN_FIXED); \
    (it).msg = NULL; \
    while (playback_next_entry_unpacked(&(it)))

#define DEVICE_REF "device_id"
#define RC_REF "rc"
#define VAL_REF "val"
#define MSG_REF "msg"
#define KEY_REF "key"
#define LIST_MEM_REF "list_mem"
#define MSG_SET_REF "msg_set"
#define MAX_MSGS_REF "max_msgs"
#define INVERT_FILTER_REF "invert_filter"
#define STAT_FLAGS_REF "stat_flags"
#define DYN_LIST_SIZE "APICLI_DYNAMIC_LIST_BUFFER_SIZE"

static void playback_iterator_cleanup(playback_iterator *it)
{
    if ((it->err == BCM_ERR_OK) && (it->msg != NULL))
    {
        bcmolt_msg_free(it->msg);
        it->msg = NULL;
    }
}

static bcmos_bool playback_next_entry_unpacked(playback_iterator *it)
{
    playback_iterator_cleanup(it);
    bcmos_bool ret = bcmtr_capture_entry_get_next(&it->raw.buf, &it->raw.hdr, &it->raw.msg_start);
    if (ret)
    {
        bcmolt_buf_init(&it->msg_buf, it->raw.hdr.msg_size, it->raw.msg_start, BCMOLT_BUF_ENDIAN_FIXED);
        it->err = bcmolt_msg_unpack(&it->msg_buf, &it->msg);
    }
    return ret;
}

static bcmos_errno playback_read_block(uint32_t offset, uint32_t size, uint8_t *buf)
{
    bcmos_errno err;
    bcmolt_debug_cfg debug_cfg;
    bcmolt_debug_key debug_key = { };
    bcmolt_api_capture_buffer_reader reader = { .offset = offset, .size = size };

    BCMOLT_CFG_INIT(&debug_cfg, debug, debug_key);
    BCMOLT_CFG_PROP_SET(&debug_cfg, debug, api_capture_buffer_read, reader);
    err = bcmolt_cfg_set(current_device, &debug_cfg.hdr);
    if (BCM_ERR_OK != err)
    {
        BCM_LOG(ERROR, pb_ctxt[current_device].log_id, "Failed to update reader (%u, %u)!\n", offset, size);
    }
    else
    {
        BCMOLT_CFG_INIT(&debug_cfg, debug, debug_key);
        BCMOLT_CFG_PROP_GET(&debug_cfg, debug, api_capture_buffer);
        debug_cfg.data.api_capture_buffer.val = buf;
        err = bcmolt_cfg_get(current_device, &debug_cfg.hdr);
        if (BCM_ERR_OK != err)
        {
            BCM_LOG(ERROR, pb_ctxt[current_device].log_id, "Failed to retrieve capture buffer chunk (%u, %u)!\n",
                offset, size);
        }
    }

    return err;
}

static bcmos_errno playback_read(void **buffer, uint32_t *length, bcmolt_api_capture_location *capture_location)
{
    bcmos_errno err;
    bcmolt_debug_cfg debug_cfg;
    bcmolt_debug_key debug_key = { };

    if ((buffer == NULL) || (length == NULL))
    {
        BCM_LOG(ERROR, pb_ctxt[current_device].log_id, "buffer (%p) and length (%p) cannot be NULL\n", buffer, length);
    }

    BCMOLT_CFG_INIT(&debug_cfg, debug, debug_key);
    BCMOLT_CFG_PROP_GET(&debug_cfg, debug, api_capture_stats);
    BCMOLT_CFG_PROP_GET(&debug_cfg, debug, api_capture_cfg);
    err = bcmolt_cfg_get(current_device, &debug_cfg.hdr);
    if (BCM_ERR_OK != err)
    {
        BCM_LOG(ERROR, pb_ctxt[current_device].log_id, "Failed to retrieve capture stats!\n");
    }
    else
    {
        void *capture_buffer;
        uint32_t buf_size = debug_cfg.data.api_capture_stats.readable_bytes;
        uint32_t offset = 0;

        *capture_location = debug_cfg.data.api_capture_cfg.location;

        BCM_LOG(DEBUG, pb_ctxt[current_device].log_id, "Retrieving %u byte buffer\n", buf_size);
        capture_buffer = bcmos_alloc(buf_size);
        if (NULL != capture_buffer)
        {
            while ((offset + CHUNK_SIZE) < buf_size)
            {
                BCM_LOG(DEBUG, pb_ctxt[current_device].log_id, "Reading bytes %u - %u\n", offset, offset + CHUNK_SIZE);
                err = playback_read_block(offset, CHUNK_SIZE, (uint8_t*)capture_buffer + offset);
                if (BCM_ERR_OK != err)
                {
                    break;
                }
                offset += CHUNK_SIZE;
            }

            if (BCM_ERR_OK == err)
            {
                BCM_LOG(DEBUG, pb_ctxt[current_device].log_id, "Reading bytes %u - %u\n", offset, buf_size);
                err = playback_read_block(offset, buf_size - offset, (uint8_t*)capture_buffer + offset);
            }
        }

        *buffer = capture_buffer;
        *length = buf_size;
    }

    return err;
}

static bcmos_errno playback_dump(bcmcli_session *session, void *capture_buf, uint32_t buf_size)
{
    playback_iterator it;
    bcmos_errno err = BCM_ERR_OK;

    FOR_EACH_PLAYBACK_MSG(it, capture_buf, buf_size)
    {
        BCM_LOG(DEBUG, pb_ctxt[current_device].log_id, "Dumping message at %u of %u (%u)\n",
                bcmolt_buf_get_used(&it.raw.buf), buf_size, it.raw.hdr.msg_size);
        bcmcli_session_print(session, "\n%08x %u:\n", it.raw.hdr.timestamp, it.raw.hdr.event);
        if (BCM_ERR_OK == it.err)
        {
            err = apicli_msg_dump(session, it.msg);
            BCM_LOG(DEBUG, pb_ctxt[current_device].log_id, "Dump status: %s\n", bcmos_strerror(err));
        }
        else
        {
            BCM_LOG(DEBUG, pb_ctxt[current_device].log_id, "Unpacking failed: %s\n", bcmos_strerror(err));
            if ((it.raw.msg_start + it.raw.hdr.msg_size) > (it.raw.buf.start + it.raw.buf.len))
            {
                bcmcli_session_print(session, "Message length is insane!\n");
            }
            else
            {
                bcmcli_session_hexdump(session, it.raw.msg_start, 0, it.raw.hdr.msg_size, NULL);
            }
        }
    }

    return err;
}

static bcmos_bool playback_should_send(bcmolt_api_capture_location capture_location, bcmtr_cld_event_type event_type)
{
    switch (capture_location)
    {
        case BCMOLT_API_CAPTURE_LOCATION_DEVICE:
            switch (event_type)
            {
                case BCMTR_CLD_EV_RECV:
                case BCMTR_CLD_EV_RECV_DISCARD:
                    return BCMOS_TRUE;
                default:
                    return BCMOS_FALSE;
            }
        case BCMOLT_API_CAPTURE_LOCATION_HOST:
            switch (event_type)
            {
                case BCMTR_CLD_EV_SEND:
                case BCMTR_CLD_EV_RESEND:
                    return BCMOS_TRUE;
                default:
                    return BCMOS_FALSE;
            }
        default:
            return BCMOS_FALSE;
    }
}

/*lint -e{429} */
static bcmos_errno playback_replay(
    bcmolt_devid device,
    void *capture_buf,
    uint32_t buf_size,
    bcmolt_api_capture_location location,
    bcmos_bool keep_time)
{
    bcmos_errno err = BCM_ERR_OK;
    playback_iterator_raw it;
    uint32_t last_time_us = 0;
    bcmos_bool first = BCMOS_TRUE;

    FOR_EACH_CAPTURE_ENTRY(it, capture_buf, buf_size)
    {
        bcmolt_buf msg_buf;
        bcmolt_msg *msg = NULL;

        BCM_LOG(DEBUG, pb_ctxt[device].log_id, "Processing message (%u,%u,%u)\n",
                it.hdr.event, it.hdr.timestamp, it.hdr.msg_size);
        if (playback_should_send(location, (bcmtr_cld_event_type)it.hdr.event))
        {
            if (keep_time)
            {
                if (!first)
                {
                    /* approximate original timing; doesn't account for processing time in this code - this could be
                       improved */
                    BCM_LOG(DEBUG, pb_ctxt[device].log_id, "Sleeping for %u us\n", it.hdr.timestamp - last_time_us);
                    bcmos_usleep(it.hdr.timestamp - last_time_us);
                }
                else
                {
                    first = BCMOS_FALSE;
                }
                last_time_us = it.hdr.timestamp;
            }
            BCM_LOG(DEBUG, pb_ctxt[device].log_id, "Unpacking message\n");
            bcmolt_buf_init(&msg_buf, it.hdr.msg_size, it.msg_start, BCMOLT_BUF_ENDIAN_FIXED);
            err = bcmolt_msg_unpack(&msg_buf, &msg);
            if (BCM_ERR_OK == err)
            {
                BCM_LOG(DEBUG, pb_ctxt[device].log_id, "Sending message\n");
                err = bcmtr_send(device, msg, BCMTR_SEND_FLAGS_NONE);
                bcmolt_msg_free(msg);
                if (BCM_ERR_OK != err)
                {
                    BCM_LOG(INFO, pb_ctxt[device].log_id, "Sending failed: %s\n", bcmos_strerror(err));
                    return err;
                }
            }
            else
            {
                BCM_LOG(INFO, pb_ctxt[device].log_id, "Unpacking failed: %s\n", bcmos_strerror(err));
                return err;
            }
        }
    }

    return err;
}

static bcmos_errno playback_cli_dump(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    bcmos_errno err;
    void *capture_buffer;
    uint32_t buf_size;
    bcmolt_api_capture_location location;

    err = playback_read(&capture_buffer, &buf_size, &location);

    if (BCM_ERR_OK == err)
    {
        bcmcli_print(session, "Capture from %s:\n", cap_loc_str[location]);
        playback_dump(session, capture_buffer, buf_size);
    }

    bcmos_free(capture_buffer);

    return err;
}

static void playback_fw_version_get(bcmolt_devid device, bcmolt_firmware_sw_version *fw)
{
    bcmos_errno err;
    bcmolt_device_cfg dev_cfg;
    bcmolt_device_key dev_key = { };

    BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
    BCMOLT_CFG_PROP_GET(&dev_cfg, device, firmware_sw_version);
    err = bcmolt_cfg_get(device, &dev_cfg.hdr);
    if (BCM_ERR_OK != err)
    {
        BCM_LOG(WARNING, pb_ctxt[device].log_id, "Failed to retrieve fw version!\n");
    }
    else
    {
        *fw = dev_cfg.data.firmware_sw_version;
    }
}

static void playback_host_version_get(bcmolt_devid device, bcmolt_host_sw_version *host)
{
    bcmos_errno err;
    bcmolt_device_cfg dev_cfg;
    bcmolt_device_key dev_key = { };

    BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
    BCMOLT_CFG_PROP_GET(&dev_cfg, device, host_sw_version);
    err = bcmolt_cfg_get(device, &dev_cfg.hdr);
    if (BCM_ERR_OK != err)
    {
        BCM_LOG(WARNING, pb_ctxt[device].log_id, "Failed to retrieve host version!\n");
    }
    else
    {
        *host = dev_cfg.data.host_sw_version;
    }
}

static bcmos_errno playback_cli_save(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    const char *filename = bcmcli_find_named_parm(session, "file")->value.string;
    bcmolt_playback mpb = {};
    bcmos_errno err;
    FILE *file;
    uint32_t temp;

    err = playback_read(&mpb.capture_buffer, &mpb.buf_size, &mpb.location);

    if (BCM_ERR_OK == err)
    {
        playback_fw_version_get(current_device, &mpb.fw_ver);
        playback_host_version_get(current_device, &mpb.host_ver);

        file = fopen(filename, "wb");
        /* write file version */
        temp = BCMOLT_BUF_ENDIAN_CPU_TO_BUF(U32, VERSION1);
        fwrite(&temp, sizeof(uint32_t), 1, file);
        /* write capture location */
        temp = BCMOLT_BUF_ENDIAN_CPU_TO_BUF(U32, (uint32_t)mpb.location);
        fwrite(&temp, sizeof(uint32_t), 1, file);
        /* write firmware version */
        fwrite(&mpb.fw_ver.major, sizeof(uint8_t), 1, file);
        fwrite(&mpb.fw_ver.minor, sizeof(uint8_t), 1, file);
        fwrite(&mpb.fw_ver.revision, sizeof(uint8_t), 1, file);
        temp = BCMOLT_BUF_ENDIAN_CPU_TO_BUF(U32, mpb.fw_ver.model);
        fwrite(&temp, sizeof(uint32_t), 1, file);
        fwrite(mpb.fw_ver.build_time, sizeof(mpb.fw_ver.build_time), 1, file);
        /* write host version */
        fwrite(&mpb.host_ver.major, sizeof(uint8_t), 1, file);
        fwrite(&mpb.host_ver.minor, sizeof(uint8_t), 1, file);
        fwrite(&mpb.host_ver.revision, sizeof(uint8_t), 1, file);
        temp = BCMOLT_BUF_ENDIAN_CPU_TO_BUF(U32, mpb.host_ver.model);
        fwrite(&temp, sizeof(uint32_t), 1, file);
        fwrite(mpb.host_ver.build_time, sizeof(mpb.host_ver.build_time), 1, file);
        /* write capture buffer */
        temp = BCMOLT_BUF_ENDIAN_CPU_TO_BUF(U32, mpb.buf_size);
        fwrite(&temp, sizeof(uint32_t), 1, file);
        fwrite(mpb.capture_buffer, mpb.buf_size, 1, file);
        fclose(file);
    }

    bcmos_free(mpb.capture_buffer);

    return err;
}

static bcmos_bool playback_version_match(const bcmolt_playback *mpb)
{
    bcmolt_firmware_sw_version fw_curr = {};
    bcmolt_host_sw_version host_curr = {};

    playback_fw_version_get(current_device, &fw_curr);
    playback_host_version_get(current_device, &host_curr);

    if ((mpb->fw_ver.model != fw_curr.model) || (mpb->host_ver.model != host_curr.model) ||
        (fw_curr.model == 0) || (host_curr.model == 0))
    {
        BCM_LOG(WARNING, pb_ctxt[current_device].log_id,
                "Possible version mismatch: Capture FW %u, HOST %u; Current FW %u, HOST %u\n",
                mpb->fw_ver.model, mpb->host_ver.model, fw_curr.model, host_curr.model);
        return BCMOS_FALSE;
    }

    return BCMOS_TRUE;
}

static bcmos_errno playback_file_open(const char *filename, bcmolt_playback *mpb)
{
    FILE *file;
    uint32_t temp;
    bcmos_errno err = BCM_ERR_OK;
    uint32_t items_read;

    file = fopen(filename, "rb");
    items_read = fread(&temp, sizeof(uint32_t), 1, file);
    if (items_read != 1)
        return BCM_ERR_PARSE;

    mpb->version = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U32, temp);
    switch (mpb->version)
    {
        case VERSION0:
            items_read = fread(&temp, sizeof(uint32_t), 1, file);
            if (items_read != 1)
                break;
            temp = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U32, temp);
            mpb->location = (bcmolt_api_capture_location)temp;
            items_read = fread(&temp, sizeof(uint32_t), 1, file);
            if (items_read != 1)
                break;
            mpb->buf_size = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U32, temp);
            mpb->capture_buffer = bcmos_alloc(mpb->buf_size);
            items_read = fread(mpb->capture_buffer, mpb->buf_size, 1, file);
            if (items_read != 1)
                break;
            break;
        case VERSION1:
            /* read capture location */
            items_read = fread(&temp, sizeof(uint32_t), 1, file);
            if (items_read != 1)
                break;
            temp = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U32, temp);
            mpb->location = (bcmolt_api_capture_location)temp;
            /* read firmware version */
            items_read = fread(&mpb->fw_ver.major, sizeof(uint8_t), 1, file);
            if (items_read != 1)
                break;
            items_read = fread(&mpb->fw_ver.minor, sizeof(uint8_t), 1, file);
            if (items_read != 1)
                break;
            items_read = fread(&mpb->fw_ver.revision, sizeof(uint8_t), 1, file);
            if (items_read != 1)
                break;
            items_read = fread(&temp, sizeof(uint32_t), 1, file);
            if (items_read != 1)
                break;
            mpb->fw_ver.model = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U32, temp);
            items_read = fread(mpb->fw_ver.build_time, sizeof(mpb->fw_ver.build_time), 1, file);
            if (items_read != 1)
                break;
            /* read host version */
            items_read = fread(&mpb->host_ver.major, sizeof(uint8_t), 1, file);
            if (items_read != 1)
                break;
            items_read = fread(&mpb->host_ver.minor, sizeof(uint8_t), 1, file);
            if (items_read != 1)
                break;
            items_read = fread(&mpb->host_ver.revision, sizeof(uint8_t), 1, file);
            if (items_read != 1)
                break;
            items_read = fread(&temp, sizeof(uint32_t), 1, file);
            if (items_read != 1)
                break;
            mpb->host_ver.model = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U32, temp);
            items_read = fread(mpb->host_ver.build_time, sizeof(mpb->host_ver.build_time), 1, file);
            if (items_read != 1)
                break;
            /* read capture buffer */
            items_read = fread(&temp, sizeof(uint32_t), 1, file);
            if (items_read != 1)
                break;
            mpb->buf_size = BCMOLT_BUF_ENDIAN_BUF_TO_CPU(U32, temp);
            mpb->capture_buffer = bcmos_alloc(mpb->buf_size);
            items_read = fread(mpb->capture_buffer, mpb->buf_size, 1, file);
            if (items_read != 1)
                break;
            break;
        default:
            BCM_LOG(ERROR, pb_ctxt[current_device].log_id, "Unknown version: %u\n", mpb->version);
            err = BCM_ERR_PARSE;
            break;
    }

    fclose(file);

    return err;
}

static bcmos_errno playback_cli_replay(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    const char *filename = bcmcli_find_named_parm(session, "file")->value.string;
    bcmos_bool ignore_ver = BCMOS_FALSE;
    bcmos_errno err;
    bcmolt_playback mpb = {};

    bcmcli_cmd_parm *iv_parm = bcmcli_find_named_parm(session, "ignore_version");
    if (iv_parm != NULL)
    {
        ignore_ver = iv_parm->value.enum_val == (long)BCMOS_TRUE;
    }

    err = playback_file_open(filename, &mpb);

    if (BCM_ERR_OK == err)
    {
        if (playback_version_match(&mpb) || ignore_ver)
        {
            err = playback_replay(current_device, mpb.capture_buffer, mpb.buf_size, mpb.location, BCMOS_TRUE);
        }
        else
        {
            bcmcli_print(session, "Possible version mismatch; use ignore_version=yes to force playback\n");
            err = BCM_ERR_IMAGE_TYPE;
        }
        bcmos_free(mpb.capture_buffer);
    }

    return err;
}

static bcmos_errno playback_api_cli_append_prop(
    bcmolt_string *api_cli,
    uint32_t size,
    void *data,
    const bcmcli_prop_descr *pd,
    const char *prefix)
{
    bcmos_errno err;
    bcmcli_session *str;
    void *prop_data = (void *)((long)data + pd->offset);

    BCMOS_CHECK_RETURN_ERROR(pd->offset >= size, BCM_ERR_INTERNAL);
    err = bcmcli_session_open_string(&str, api_cli);
    BCMOS_RETURN_IF_ERROR(err);
    err = apicli_dump_prop_param(str, pd, prop_data, prefix);
    bcmcli_session_close(str);
    BCMOS_RETURN_IF_ERROR(err);

    return BCM_ERR_OK;
}

static bcmos_errno playback_api_cli_key_write(
    bcmolt_string* api_cli,
    const bcmolt_msg* msg,
    uint32_t key_size,
    uint32_t key_offset)
{
    bcmos_errno err;
    const bcmcli_prop_descr *pd;
    void *data = (void *)((long)msg + key_offset);

    for (uint16_t prop = 0;
         api_cli_object_property(msg->obj_type, BCMOLT_MGT_GROUP_KEY, 0, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        err = playback_api_cli_append_prop(api_cli, key_size, data, pd, " ");
        BCMOS_RETURN_IF_ERROR(err);
    }

    return BCM_ERR_OK;
}

static bcmos_errno playback_api_cli_pm_write(bcmolt_string *api_cli, const bcmolt_msg* msg, bcmolt_presence_mask pm)
{
    int n;
    const bcmcli_prop_descr *pd;

    for (uint16_t prop = 0;
         api_cli_object_property(msg->obj_type, msg->group, msg->subgroup, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        if (!(pm & (1ULL << prop)))
        {
            continue;
        }
        n = bcmolt_string_append(api_cli, " %s=yes", pd->name);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }

    return BCM_ERR_OK;
}

static bcmos_errno playback_api_cli_props_write(
    bcmolt_string *api_cli,
    const bcmolt_msg* msg,
    const char *prefix,
    uint32_t size,
    uint32_t offset)
{
    bcmos_errno err;
    const bcmcli_prop_descr *pd;
    void *data = (void *)((long)msg + offset);

    for (uint16_t prop = 0;
         api_cli_object_property(msg->obj_type, msg->group, msg->subgroup, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        if (!(msg->presence_mask & (1ULL << prop)))
        {
            continue;
        }
        err = playback_api_cli_append_prop(api_cli, size, data, pd, prefix);
        BCMOS_RETURN_IF_ERROR(err);
    }

    return BCM_ERR_OK;
}

static bcmos_errno playback_api_cli_cmd_get(
    bcmolt_string *api_cli,
    const bcmolt_msg* msg,
    const char *cmd,
    pb_cli_extra extra_parms,
    pb_fields field_parms)
{
    int n;
    bcmos_errno err;
    const char *name;
    const char *desc;
    uint32_t key_size;
    uint32_t key_offset;
    uint32_t data_size;
    uint32_t data_offset;

    BCM_LOG(DEBUG, pb_ctxt[current_device].log_id, "Start %s\n", cmd);

    err = api_cli_object_name(msg->obj_type, &name, &desc);
    BCMOS_RETURN_IF_ERROR(err);

    n = bcmolt_string_append(api_cli, "/api/%s object=%s", cmd, name);
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);

    switch (extra_parms)
    {
        case PB_CLI_EXTRA_MULTI:
            n = bcmolt_string_append(
                api_cli,
                " max_msgs=%u filter_invert=%s",
                msg->msg_set->max_instances,
                BITS_SET(msg->msg_set->filter_flags, BCMOLT_FILTER_FLAGS_INVERT_SELECTION) ? "yes" : "no");
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            break;
        case PB_CLI_EXTRA_STAT:
            n = bcmolt_string_append(api_cli, " clear=%s", BITS_SET(msg->type, BCMOLT_MSG_TYPE_CLEAR) ? "yes" : "no");
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            break;
        case PB_CLI_EXTRA_SUBGROUP:
            err = api_cli_object_subgroup_name(msg->obj_type, msg->group, msg->subgroup, &name, &desc);
            BCMOS_RETURN_IF_ERROR(err);
            n = bcmolt_string_append(api_cli, " sub=%s", name);
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            break;
        default:
            break;
    }

    /* get message info */
    err = api_cli_object_struct_size(
        msg->obj_type,
        msg->group,
        msg->subgroup,
        &key_size,
        &key_offset,
        &data_size,
        &data_offset);
    BCMOS_RETURN_IF_ERROR(err);

    if (BCMOLT_MGT_GROUP_AUTO_CFG != msg->group)
    {
        /* write key */
        err = playback_api_cli_key_write(api_cli, msg, key_size, key_offset);
        BCMOS_RETURN_IF_ERROR(err);
    }

    switch (field_parms)
    {
        case PB_FIELDS_GET:
            /* write presence mask */
            err = playback_api_cli_pm_write(api_cli, msg, msg->presence_mask);
            BCMOS_RETURN_IF_ERROR(err);
            break;
        case PB_FIELDS_MULTI:
            /* write filter */
            err = playback_api_cli_props_write(api_cli, msg, " filter.", data_size, data_offset);
            BCMOS_RETURN_IF_ERROR(err);
            /* write presence mask */
            err = playback_api_cli_pm_write(api_cli, msg, msg->msg_set->presence_mask);
            BCMOS_RETURN_IF_ERROR(err);
            break;
        case PB_FIELDS_SET:
            /* write properties */
            err = playback_api_cli_props_write(api_cli, msg, " ", data_size, data_offset);
            BCMOS_RETURN_IF_ERROR(err);
            break;
        default:
            break;
    }

    n = bcmolt_string_append(api_cli, "\n");
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);

    BCM_LOG(DEBUG, pb_ctxt[current_device].log_id, "End %s\n", cmd);

    return err;
}

static bcmos_errno playback_api_cli_get(bcmolt_string* api_cli, const bcmolt_msg* msg)
{
    switch (msg->group)
    {
        case BCMOLT_MGT_GROUP_CFG:
            switch (msg->type)
            {
                case BCMOLT_MSG_TYPE_GET:
                    return playback_api_cli_cmd_get(api_cli, msg, "get", PB_CLI_EXTRA_NONE, PB_FIELDS_GET);
                case BCMOLT_MSG_TYPE_GET_MULTI:
                    return playback_api_cli_cmd_get(api_cli, msg, "multiget", PB_CLI_EXTRA_MULTI, PB_FIELDS_MULTI);
                case BCMOLT_MSG_TYPE_SET:
                    return playback_api_cli_cmd_get(api_cli, msg, "set", PB_CLI_EXTRA_NONE, PB_FIELDS_SET);
                case BCMOLT_MSG_TYPE_CLEAR:
                    return playback_api_cli_cmd_get(api_cli, msg, "clear", PB_CLI_EXTRA_NONE, PB_FIELDS_NONE);
                default:
                    return BCM_ERR_INTERNAL;
            }
            break;
        case BCMOLT_MGT_GROUP_STAT:
            return playback_api_cli_cmd_get(api_cli, msg, "stat", PB_CLI_EXTRA_STAT, PB_FIELDS_GET);
        case BCMOLT_MGT_GROUP_STAT_CFG:
            switch (msg->type)
            {
                case BCMOLT_MSG_TYPE_GET:
                    return playback_api_cli_cmd_get(api_cli, msg, "saget", PB_CLI_EXTRA_SUBGROUP, PB_FIELDS_NONE);
                case BCMOLT_MSG_TYPE_SET:
                    return playback_api_cli_cmd_get(api_cli, msg, "saset", PB_CLI_EXTRA_SUBGROUP, PB_FIELDS_SET);
                default:
                    return BCM_ERR_INTERNAL;
            }
            break;
        case BCMOLT_MGT_GROUP_AUTO_CFG:
            switch (msg->type)
            {
                case BCMOLT_MSG_TYPE_GET:
                    return playback_api_cli_cmd_get(api_cli, msg, "acget", PB_CLI_EXTRA_NONE, PB_FIELDS_GET);
                case BCMOLT_MSG_TYPE_SET:
                    return playback_api_cli_cmd_get(api_cli, msg, "acset", PB_CLI_EXTRA_NONE, PB_FIELDS_SET);
                default:
                    return BCM_ERR_INTERNAL;
            }
            break;
        case BCMOLT_MGT_GROUP_OPER:
            return playback_api_cli_cmd_get(api_cli, msg, "oper", PB_CLI_EXTRA_SUBGROUP, PB_FIELDS_SET);
        case BCMOLT_MGT_GROUP_PROXY:
            return playback_api_cli_cmd_get(api_cli, msg, "send", PB_CLI_EXTRA_SUBGROUP, PB_FIELDS_SET);
        default:
            return BCM_ERR_INTERNAL;
    }
}

static bcmos_errno playback_convert_api_cli(bcmolt_playback *mpb, FILE *out_file)
{
    playback_iterator it;
    bcmos_errno err;
    bcmolt_string *str;

    err = bcmolt_string_create(&str, 2048);
    BCMOS_RETURN_IF_ERROR(err);
    FOR_EACH_PLAYBACK_MSG(it, mpb->capture_buffer, mpb->buf_size)
    {
        if (playback_should_send(mpb->location, (bcmtr_cld_event_type)it.raw.hdr.event))
        {
            if (BCM_ERR_OK == it.err)
            {
                bcmolt_string_reset(str);
                err = playback_api_cli_get(str, it.msg);
                fwrite(bcmolt_string_get(str), sizeof(char), strlen(bcmolt_string_get(str)), out_file);
            }
            else
            {
                err = it.err;
                BCM_LOG(ERROR, pb_ctxt[current_device].log_id, "Unpacking failed: %s\n", bcmos_strerror(err));
            }
        }
    }
    bcmolt_string_destroy(str);

    return err;
}

static bcmos_bool playback_field_contains_var_list(const bcmcli_type_descr *type)
{
    if (type == NULL)
    {
        return BCMOS_FALSE;
    }

    if (type->base_type == BCMOLT_BASE_TYPE_ID_ARR_DYN)
    {
        return BCMOS_TRUE;
    }
    else if (type->base_type == BCMOLT_BASE_TYPE_ID_ARR_FIXED)
    {
        return playback_field_contains_var_list(type->x.arr_fixed.elem_type);
    }
    else if (type->base_type == BCMOLT_BASE_TYPE_ID_STRUCT)
    {
        for (uint16_t i = 0; i < type->x.s.num_fields; ++i)
        {
            if (playback_field_contains_var_list(type->x.s.fields[i].type))
            {
                return BCMOS_TRUE;
            }
        }
    }
    else if (type->base_type == BCMOLT_BASE_TYPE_ID_UNION)
    {
        for (uint16_t i = 0; i < type->x.u.num_common_fields; ++i)
        {
            if (playback_field_contains_var_list(type->x.u.common_fields[i].type))
            {
                return BCMOS_TRUE;
            }
        }
        for (uint16_t i = 0; type->x.u.common_fields[type->x.u.classifier_idx].type->x.e[i].name != NULL; ++i)
        {
            if (playback_field_contains_var_list(type->x.u.union_fields[i].type))
            {
                return BCMOS_TRUE;
            }
        }
    }
    else
    {
        /* not a variable sized list */
    }

    return BCMOS_FALSE;
}

static bcmos_bool playback_msg_contains_var_list(const bcmolt_msg* msg)
{
    const bcmcli_prop_descr *pd;

    for (uint16_t prop = 0;
         api_cli_object_property(msg->obj_type, msg->group, msg->subgroup, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        if (playback_field_contains_var_list(pd->type))
        {
            return BCMOS_TRUE;
        }
    }

    return BCMOS_FALSE;
}

static bcmos_errno playback_string_write_upper(bcmolt_string *dest, const char* src)
{
    int n;

    while (*src != '\0')
    {
        n = bcmolt_string_append(dest, "%c", (char)toupper((int)*src));
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        ++src;
    }

    return BCM_ERR_OK;
}

static bcmos_errno playback_c_api_pm_write(
    bcmolt_string *c_api,
    const bcmolt_msg* msg,
    bcmolt_presence_mask pm,
    const char *extra,
    const char *field,
    const char *obj)
{
    int n;
    bcmos_errno err;
    const bcmcli_prop_descr *pd;

    for (uint16_t prop = 0;
         api_cli_object_property(msg->obj_type, msg->group, msg->subgroup, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        if (!(pm & (1ULL << prop)))
        {
            continue;
        }
        n = bcmolt_string_append(c_api, "\tBCMOLT_%s", extra);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        err = playback_string_write_upper(c_api, apicli_mgt_group_to_str(msg->group));
        BCMOS_RETURN_IF_ERROR(err);
        n = bcmolt_string_append(c_api, "_PROP_GET(%s, %s, %s);\n", field, obj, pd->name);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }

    return BCM_ERR_OK;
}

static bcmos_errno playback_c_api_append_init(
    bcmolt_string *c_api,
    void *data,
    const bcmcli_type_descr *td,
    const char* name)
{
    bcmos_errno rc;
    bcmcli_session *str;

    rc = bcmcli_session_open_string(&str, c_api);
    BCMOS_RETURN_IF_ERROR(rc);
    rc = apicli_dump_dyn_array(str, td, data, name);
    bcmcli_session_close(str);
    BCMOS_RETURN_IF_ERROR(rc);

    return BCM_ERR_OK;
}


static bcmos_errno playback_c_api_append_prop(
    bcmolt_string *c_api,
    uint32_t size,
    void *data,
    const bcmcli_prop_descr *pd)
{
    bcmos_errno err;
    bcmcli_session *str;
    void *prop_data = (void *)((long)data + pd->offset);

    BCMOS_CHECK_RETURN_ERROR(pd->offset >= size, BCM_ERR_INTERNAL);
    err = bcmcli_session_open_string(&str, c_api);
    BCMOS_RETURN_IF_ERROR(err);
    err = apicli_dump_prop_initializer(str, pd, prop_data);
    bcmcli_session_close(str);
    BCMOS_RETURN_IF_ERROR(err);

    return BCM_ERR_OK;
}

static bcmos_errno playback_c_api_make_var_lists(
    bcmolt_string *c_api,
    const bcmcli_type_descr *type,
    void *data,
    const char *name)
{
    int n;
    bcmos_errno rc;

    if (type == NULL)
    {
        return BCM_ERR_OK;
    }

    if (type->base_type == BCMOLT_BASE_TYPE_ID_ARR_DYN)
    {
        n = bcmolt_string_append(c_api, "\t%s %s[] = ", type->x.arr_dyn.elem_type->name, name);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        rc = playback_c_api_append_init(c_api, data, type, name);
        BCMOS_RETURN_IF_ERROR(rc);
        n = bcmolt_string_append(c_api, ";\n");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }
    else if (type->base_type == BCMOLT_BASE_TYPE_ID_ARR_FIXED)
    {
        for (uint16_t i = 0; i < type->x.arr_fixed.size; ++i)
        {
            char index_name[64];

            sprintf(index_name, "%s%u", name, i);
            rc = playback_c_api_make_var_lists(c_api, type->x.arr_fixed.elem_type, data, index_name);
            BCMOS_RETURN_IF_ERROR(rc);
            data = (void*)((long)data + type->x.arr_fixed.elem_type->size);
        }
    }
    else if (type->base_type == BCMOLT_BASE_TYPE_ID_STRUCT)
    {
        for (uint16_t i = 0; i < type->x.s.num_fields; ++i)
        {
            const bcmcli_field_descr *field = &type->x.s.fields[i];
            rc = playback_c_api_make_var_lists(c_api, field->type, (void*)((long)data + field->offset), field->name);
            BCMOS_RETURN_IF_ERROR(rc);
        }
    }
    else if (type->base_type == BCMOLT_BASE_TYPE_ID_UNION)
    {
        for (uint16_t i = 0; i < type->x.u.num_common_fields; ++i)
        {
            const bcmcli_field_descr *field = &type->x.u.common_fields[i];
            rc = playback_c_api_make_var_lists(c_api, field->type, (void*)((long)data + field->offset), field->name);
            BCMOS_RETURN_IF_ERROR(rc);
        }
        for (uint16_t i = 0; type->x.u.common_fields[type->x.u.classifier_idx].type->x.e[i].name != NULL; ++i)
        {
            const bcmcli_field_descr *field = &type->x.u.union_fields[i];
            rc = playback_c_api_make_var_lists(c_api, field->type, (void*)((long)data + field->offset), field->name);
            BCMOS_RETURN_IF_ERROR(rc);
        }
    }
    else
    {
        /* not a variable sized list */
    }

    return BCM_ERR_OK;
}

static bcmos_errno playback_c_api_props_write(
    bcmolt_string *c_api,
    const bcmolt_msg* msg,
    const char* object,
    uint32_t size,
    uint32_t offset)
{
    int n;
    bcmos_errno err;
    const char *subgroup;
    const char *desc;
    const bcmcli_prop_descr *pd;
    void *data = (void *)((long)msg + offset);

    for (uint16_t prop = 0;
         api_cli_object_property(msg->obj_type, msg->group, msg->subgroup, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        if (!(msg->presence_mask & (1ULL << prop)))
        {
            continue;
        }
        playback_c_api_make_var_lists(c_api, pd->type, (void*)((long)data + pd->offset), pd->name);
    }

    for (uint16_t prop = 0;
         api_cli_object_property(msg->obj_type, msg->group, msg->subgroup, prop, &pd) == BCM_ERR_OK;
         ++prop)
    {
        if (!(msg->presence_mask & (1ULL << prop)))
        {
            continue;
        }
        if ((pd->type->base_type == BCMOLT_BASE_TYPE_ID_STRUCT) ||
            (pd->type->base_type == BCMOLT_BASE_TYPE_ID_UNION) ||
            (pd->type->base_type == BCMOLT_BASE_TYPE_ID_ARR_DYN) ||
            (pd->type->base_type == BCMOLT_BASE_TYPE_ID_ARR_FIXED))
        {
            n = bcmolt_string_append(c_api, "\t%s "VAL_REF" = ", pd->type->name);
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            err = playback_c_api_append_prop(c_api, size, data, pd);
            BCMOS_RETURN_IF_ERROR(err);
            n = bcmolt_string_append(c_api, ";\n");
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            n = bcmolt_string_append(c_api, "\tBCMOLT_");
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            err = playback_string_write_upper(c_api, apicli_mgt_group_to_str(msg->group));
            BCMOS_RETURN_IF_ERROR(err);
            n = bcmolt_string_append(c_api, "_PROP_SET(&msg, %s", object);
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            if ((msg->group == BCMOLT_MGT_GROUP_OPER) || (msg->group == BCMOLT_MGT_GROUP_PROXY))
            {
                err = api_cli_object_subgroup_name(msg->obj_type, msg->group, msg->subgroup, &subgroup, &desc);
                BCMOS_RETURN_IF_ERROR(err);
                n = bcmolt_string_append(c_api, ", %s", subgroup);
                BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            }
            n = bcmolt_string_append(c_api, ", %s, "VAL_REF");\n", pd->name);
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        }
        else
        {
            n = bcmolt_string_append(c_api, "\tBCMOLT_");
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            err = playback_string_write_upper(c_api, apicli_mgt_group_to_str(msg->group));
            BCMOS_RETURN_IF_ERROR(err);
            n = bcmolt_string_append(c_api, "_PROP_SET(&msg, %s", object);
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            if ((msg->group == BCMOLT_MGT_GROUP_OPER) || (msg->group == BCMOLT_MGT_GROUP_PROXY))
            {
                err = api_cli_object_subgroup_name(msg->obj_type, msg->group, msg->subgroup, &subgroup, &desc);
                BCMOS_RETURN_IF_ERROR(err);
                n = bcmolt_string_append(c_api, ", %s", subgroup);
                BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            }
            n = bcmolt_string_append(c_api, ", %s, ", pd->name);
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            err = playback_c_api_append_prop(c_api, size, data, pd);
            BCMOS_RETURN_IF_ERROR(err);
            n = bcmolt_string_append(c_api, ");\n");
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        }
    }

    return BCM_ERR_OK;
}

static bcmos_errno playback_c_api_code_get(
    bcmolt_string* c_api,
    const bcmolt_msg* msg,
    const char *call,
    pb_fields field_parms)
{
    int n;
    bcmos_errno err;
    const char *object;
    const char *group;
    const char *subgroup;
    const char *desc;
    uint32_t key_size;
    uint32_t key_offset;
    uint32_t data_size;
    uint32_t data_offset;
    void *data;
    const bcmcli_prop_descr *pd;
    bcmos_bool var_list = (BCMOLT_MSG_TYPE_GET == msg->type) && playback_msg_contains_var_list(msg);

    err = api_cli_object_name(msg->obj_type, &object, &desc);
    BCMOS_RETURN_IF_ERROR(err);
    err = api_cli_object_subgroup_name(msg->obj_type, msg->group, msg->subgroup, &subgroup, &desc);
    BCMOS_RETURN_IF_ERROR(err);

    group = apicli_mgt_group_to_str(msg->group);

    /* get message info */
    err = api_cli_object_struct_size(
        msg->obj_type,
        msg->group,
        msg->subgroup,
        &key_size,
        &key_offset,
        &data_size,
        &data_offset);
    BCMOS_RETURN_IF_ERROR(err);

    /* init variables */
    n = bcmolt_string_append(c_api, "\t{\n");
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    if ((msg->group == BCMOLT_MGT_GROUP_OPER) || (msg->group == BCMOLT_MGT_GROUP_PROXY))
    {
        n = bcmolt_string_append(c_api, "\tbcmolt_%s_%s "MSG_REF";\n", object, subgroup);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }
    else
    {
        n = bcmolt_string_append(c_api, "\tbcmolt_%s_%s "MSG_REF";\n", object, group);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }
    n = bcmolt_string_append(c_api, "\tbcmolt_%s_key "KEY_REF" = { };\n", object);
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);

    if (var_list)
    {
        n = bcmolt_string_append(c_api, "\tuint8_t* "LIST_MEM_REF";\n");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }

    if (msg->type == BCMOLT_MSG_TYPE_GET_MULTI)
    {
        n = bcmolt_string_append(c_api, "\tbcmolt_msg_set* "MSG_SET_REF" = NULL;\n");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        n = bcmolt_string_append(c_api, "\tuint32_t "MAX_MSGS_REF";\n");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        n = bcmolt_string_append(c_api, "\tbcmos_bool "INVERT_FILTER_REF";\n\n");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        n = bcmolt_string_append(c_api, "\t"MAX_MSGS_REF" = %d;\n", msg->msg_set->max_instances);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        n = bcmolt_string_append(c_api, "\t"INVERT_FILTER_REF" = %s;\n", BITS_SET(msg->msg_set->filter_flags, BCMOLT_FILTER_FLAGS_INVERT_SELECTION) ? "BCMOS_TRUE" : "BCMOS_FALSE");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        n = bcmolt_string_append(c_api, "\tbcmolt_msg_set_alloc(BCMOLT_OBJ_ID_");
        err = playback_string_write_upper(c_api, object);
        BCMOS_RETURN_IF_ERROR(err);
        n = bcmolt_string_append(c_api, ", BCMOLT_MGT_GROUP_");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        err = playback_string_write_upper(c_api, group);
        BCMOS_RETURN_IF_ERROR(err);
        n = bcmolt_string_append(c_api, ", "MAX_MSGS_REF", &"MSG_SET_REF");\n");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }
    else if (msg->group == BCMOLT_MGT_GROUP_STAT)
    {
        n = bcmolt_string_append(c_api, "\tbcmolt_stat_flags "STAT_FLAGS_REF";\n\n");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        n = bcmolt_string_append(c_api, "\t"STAT_FLAGS_REF" = %s;\n", BITS_SET(msg->type, BCMOLT_MSG_TYPE_CLEAR) ? "BCMOLT_STAT_FLAGS_CLEAR_ON_READ" : "BCMOLT_STAT_FLAGS_NONE");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }
    else
    {
        n = bcmolt_string_append(c_api, "\n");
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }

    /* set key */
    if (BCMOLT_MGT_GROUP_AUTO_CFG != msg->group)
    {
        /* write key */
        data = (void *)((long)msg + key_offset);
        for (uint16_t prop = 0;
             api_cli_object_property(msg->obj_type, BCMOLT_MGT_GROUP_KEY, 0, prop, &pd) == BCM_ERR_OK;
             ++prop)
        {
            n = bcmolt_string_append(c_api, "\t"KEY_REF".%s = ", pd->name);
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            if ((BCMOLT_BASE_TYPE_ID_MAC == pd->type->base_type) ||
                (BCMOLT_BASE_TYPE_ID_IPV4 == pd->type->base_type) ||
                (BCMOLT_BASE_TYPE_ID_STRUCT == pd->type->base_type) ||
                (BCMOLT_BASE_TYPE_ID_UNION == pd->type->base_type))
            {
                n = bcmolt_string_append(c_api, "(%s)", pd->type->name);
                BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            }
            err = playback_c_api_append_prop(c_api, key_size, data, pd);
            BCMOS_RETURN_IF_ERROR(err);
            n = bcmolt_string_append(c_api, ";\n");
            BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
        }
    }

    /* set properties */
    n = bcmolt_string_append(c_api, "\tBCMOLT_");
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    err = playback_string_write_upper(c_api, group);
    BCMOS_RETURN_IF_ERROR(err);
    n = bcmolt_string_append(c_api, "_INIT(&"MSG_REF", %s", object);
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    if ((msg->group == BCMOLT_MGT_GROUP_STAT_CFG) ||
        (msg->group == BCMOLT_MGT_GROUP_OPER) ||
        (msg->group == BCMOLT_MGT_GROUP_PROXY))
    {
        n = bcmolt_string_append(c_api, ", %s", subgroup);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }
    n = bcmolt_string_append(c_api, ", "KEY_REF");\n");
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);

    switch (field_parms)
    {
        case PB_FIELDS_GET:
            /* write presence mask */
            err = playback_c_api_pm_write(c_api, msg, msg->presence_mask, "", "&"MSG_REF, object);
            BCMOS_RETURN_IF_ERROR(err);
            if (var_list)
            {
                n = bcmolt_string_append(c_api, "\t"LIST_MEM_REF" = bcmos_calloc("DYN_LIST_SIZE");\n");
                BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
                n = bcmolt_string_append(
                    c_api,
                    "\tBCMOLT_CFG_LIST_BUF_SET(&"MSG_REF", %s, "LIST_MEM_REF", "DYN_LIST_SIZE");\n", object);
                BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
            }
            break;
        case PB_FIELDS_MULTI:
            /* write filter */
            err = playback_c_api_props_write(c_api, msg, object, data_size, data_offset);
            BCMOS_RETURN_IF_ERROR(err);
            /* write presence mask */
            err = playback_c_api_pm_write(c_api, msg, msg->presence_mask, "MSGSET_", MSG_SET_REF, object);
            BCMOS_RETURN_IF_ERROR(err);
            break;
        case PB_FIELDS_SET:
            /* write properties */
            err = playback_c_api_props_write(c_api, msg, object, data_size, data_offset);
            BCMOS_RETURN_IF_ERROR(err);
            break;
        default:
            break;
    }

    /* call API */
    n = bcmolt_string_append(c_api, "\t"RC_REF" = bcmolt_%s_%s("DEVICE_REF", &"MSG_REF".hdr", group, call);
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    if (msg->type == BCMOLT_MSG_TYPE_GET_MULTI)
    {
        n = bcmolt_string_append(
            c_api,
            ", ("INVERT_FILTER_REF") ? BCMOLT_FILTER_FLAGS_INVERT_SELECTION : BCMOLT_FILTER_FLAGS_NONE, "MSG_SET_REF);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }
    else if (msg->group == BCMOLT_MGT_GROUP_STAT)
    {
        n = bcmolt_string_append(c_api, ", "STAT_FLAGS_REF);
        BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    }
    else
    {
        /* do nothing */
    }
    n = bcmolt_string_append(c_api, ");\n");
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    n = bcmolt_string_append(c_api, "\tbcmos_printf(\"bcmolt_%s_%s returned %%s (%%d)\\n\", bcmos_strerror("RC_REF"), "RC_REF");\n", group, call);
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);
    n = bcmolt_string_append(c_api, "\t}\n\n");
    BCMOS_CHECK_RETURN_ERROR(n <= 0, BCM_ERR_INTERNAL);

    return BCM_ERR_OK;
}

static bcmos_errno playback_c_api_get(bcmolt_string* c_api, const bcmolt_msg* msg)
{
    switch (msg->group)
    {
        case BCMOLT_MGT_GROUP_CFG:
            switch (msg->type)
            {
                case BCMOLT_MSG_TYPE_GET:
                    return playback_c_api_code_get(c_api, msg, "get", PB_FIELDS_GET);
                case BCMOLT_MSG_TYPE_GET_MULTI:
                    return playback_c_api_code_get(c_api, msg, "get_multi", PB_FIELDS_MULTI);
                case BCMOLT_MSG_TYPE_SET:
                    return playback_c_api_code_get(c_api, msg, "set", PB_FIELDS_SET);
                case BCMOLT_MSG_TYPE_CLEAR:
                    return playback_c_api_code_get(c_api, msg, "clear", PB_FIELDS_NONE);
                default:
                    return BCM_ERR_INTERNAL;
            }
            break;
        case BCMOLT_MGT_GROUP_STAT:
            return playback_c_api_code_get(c_api, msg, "get", PB_FIELDS_GET);
        case BCMOLT_MGT_GROUP_STAT_CFG:
            switch (msg->type)
            {
                case BCMOLT_MSG_TYPE_GET:
                    return playback_c_api_code_get(c_api, msg, "get", PB_FIELDS_NONE);
                case BCMOLT_MSG_TYPE_SET:
                    return playback_c_api_code_get(c_api, msg, "set", PB_FIELDS_SET);
                default:
                    return BCM_ERR_INTERNAL;
            }
            break;
        case BCMOLT_MGT_GROUP_AUTO_CFG:
            switch (msg->type)
            {
                case BCMOLT_MSG_TYPE_GET:
                    return playback_c_api_code_get(c_api, msg, "get", PB_FIELDS_GET);
                case BCMOLT_MSG_TYPE_SET:
                    return playback_c_api_code_get(c_api, msg, "set", PB_FIELDS_SET);
                default:
                    return BCM_ERR_INTERNAL;
            }
            break;
        case BCMOLT_MGT_GROUP_OPER:
            return playback_c_api_code_get(c_api, msg, "submit", PB_FIELDS_SET);
        case BCMOLT_MGT_GROUP_PROXY:
            return playback_c_api_code_get(c_api, msg, "send", PB_FIELDS_SET);
        default:
            return BCM_ERR_INTERNAL;
    }
}

static bcmos_errno playback_convert_c_api(bcmolt_playback *mpb, FILE *out_file)
{
    playback_iterator it;
    bcmos_errno err;
    bcmolt_string *str;
    uint32_t last_time_us = 0;
    bcmos_bool first = BCMOS_TRUE;

    err = bcmolt_string_create(&str, 16384);
    BCMOS_RETURN_IF_ERROR(err);
    fprintf(out_file, "void run_playback(void)\n{\n");
    fprintf(out_file, "\tbcmolt_devid "DEVICE_REF" = %d;\n", current_device);
    fprintf(out_file, "\tbcmos_errno "RC_REF" = BCM_ERR_OK;\n\n");
    FOR_EACH_PLAYBACK_MSG(it, mpb->capture_buffer, mpb->buf_size)
    {
        if (playback_should_send(mpb->location, (bcmtr_cld_event_type)it.raw.hdr.event))
        {
            if (BCM_ERR_OK == it.err)
            {
                if (!first)
                {
                    /* approximate original timing; doesn't account for processing time in this code - this could be
                       improved */
                    fprintf(out_file, "\n\tbcmos_usleep(%u);\n\n", it.raw.hdr.timestamp - last_time_us);
                }
                else
                {
                    first = BCMOS_FALSE;
                }
                last_time_us = it.raw.hdr.timestamp;
                bcmolt_string_reset(str);
                err = playback_c_api_get(str, it.msg);
                fwrite(bcmolt_string_get(str), sizeof(char), strlen(bcmolt_string_get(str)), out_file);
            }
            else
            {
                err = it.err;
                BCM_LOG(ERROR, pb_ctxt[current_device].log_id, "Unpacking failed: %s\n", bcmos_strerror(err));
            }
        }
    }
    fprintf(out_file, "}\n");
    bcmolt_string_destroy(str);

    return err;
}

static bcmos_errno playback_convert(bcmolt_playback *mpb, pb_format format, FILE *out_file)
{
    bcmos_errno err;

    switch (format)
    {
        case PB_FORMAT_API_CLI:
            err = playback_convert_api_cli(mpb, out_file);
            break;
        case PB_FORMAT_C_API:
            err = playback_convert_c_api(mpb, out_file);
            break;
        default:
            err = BCM_ERR_PARM;
            BCM_LOG(ERROR, pb_ctxt[current_device].log_id, "Unknown format: %d\n", format);
            break;
    }

    return err;
}

static bcmos_errno playback_cli_conv(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    const char *infilename = bcmcli_find_named_parm(session, "infile")->value.string;
    const char *outfilename = bcmcli_find_named_parm(session, "outfile")->value.string;
    pb_format format = (pb_format)bcmcli_find_named_parm(session, "format")->value.enum_val;
    bcmos_bool ignore_ver = BCMOS_FALSE;
    bcmos_errno err;
    bcmolt_playback mpb = {};
    FILE *out_file;

    bcmcli_cmd_parm *iv_parm = bcmcli_find_named_parm(session, "ignore_version");
    if (iv_parm != NULL)
    {
        ignore_ver = iv_parm->value.enum_val == (long)BCMOS_TRUE;
    }

    err = playback_file_open(infilename, &mpb);

    if (BCM_ERR_OK == err)
    {
        if (playback_version_match(&mpb) || ignore_ver)
        {
            out_file = fopen(outfilename, "wb");
            playback_convert(&mpb, format, out_file);
            fclose(out_file);
        }
        else
        {
            bcmcli_print(session, "Possible version mismatch; use ignore_version=yes to force conversion\n");
            err = BCM_ERR_IMAGE_TYPE;
        }
        bcmos_free(mpb.capture_buffer);
    }

    return err;
}

void bcmolt_user_appl_playback_cli_init(bcmcli_entry *top_dir)
{
#ifdef ENABLE_CLI
    bcmcli_entry *plb_dir = bcmcli_dir_add(top_dir, "playback", "playback", BCMCLI_ACCESS_ADMIN, NULL);
    BUG_ON(NULL == plb_dir);

    static bcmcli_enum_val format_enum_table[PB_FORMAT__COUNT+1] =
    {
        {.name = "api_cli", .val = (long)PB_FORMAT_API_CLI},
        {.name = "c_api", .val = (long)PB_FORMAT_C_API},
        BCMCLI_ENUM_LAST
    };

    BCMCLI_MAKE_CMD_NOPARM(plb_dir, "dump", "dump capture", playback_cli_dump);
    BCMCLI_MAKE_CMD(plb_dir, "save", "save capture", playback_cli_save,
        BCMCLI_MAKE_PARM("file", "filename", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_NONE));
    BCMCLI_MAKE_CMD(plb_dir, "replay", "replay capture", playback_cli_replay,
        BCMCLI_MAKE_PARM("file", "filename", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_ENUM("ignore_version", "Ignore version mismatch", bcmcli_enum_bool_table, BCMCLI_PARM_FLAG_OPTIONAL));
    BCMCLI_MAKE_CMD(plb_dir, "conv", "Convert capture", playback_cli_conv,
        BCMCLI_MAKE_PARM("infile", "Input filename", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM("outfile", "Output filename", BCMCLI_PARM_STRING, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_ENUM("format", "Output format", format_enum_table, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_ENUM("ignore_version", "Ignore version mismatch", bcmcli_enum_bool_table, BCMCLI_PARM_FLAG_OPTIONAL));
#endif
}

void bcmolt_user_appl_playback_init(void)
{
    for (uint32_t i = 0; i < BCMTR_MAX_OLTS; i++)
    {
        char log_name[MAX_DEV_LOG_ID_NAME];
        snprintf(log_name, sizeof(log_name)-1, "user_appl_playback_%u", i);
        pb_ctxt[i].log_id = bcm_dev_log_id_register(log_name, DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
    }
}

