/******************************************************************************
 *
 *  <:copyright-BRCM:2016:DUAL/GPL:standard
 *  
 *     Copyright (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.
 *  
 *  :>
 *
 *****************************************************************************/
 
/**
 * @file bal_api.c
 * @brief The BAL Public API
 *
 * @addtogroup api
 */

/*@{*/

/* Project includes */
#include "bal_api.h"
#include "bal_msg.h"
#include "bal_api_worker.h"
#include "bal_obj_msg_pack_unpack.h"
#ifdef BAL_MONOLITHIC
#include <bal_worker.h>
#endif

#ifdef ENABLE_LOG
#include <bcm_dev_log.h>

/*
 * @brief The logging device id for the BAL public API
 */
dev_log_id log_id_public_api;
#endif

/*
 * @brief The global mgmt queues 
 * 
 * These are the queues through which the BAL API communicates with
 * the core, and vice versa.
 */
static bcmos_msg_queue balapi_rsp_queue;
static bcmos_msg_queue balapi_to_core_queue;

bcmos_msg_queue *p_balapi_rsp_queue;
bcmos_msg_queue *p_balapi_to_core_queue;

static bcmos_mutex balapi_lock;
static uint32_t balapi_exchange_id;
static STAILQ_HEAD(pending_req_list, bcmos_msg) pending_req_list;

static bcmos_task api_rsp_rx_thread;
static int _bal_ipc_api_rx_handler(long data);

/* Rx polling timeout (us) */
#define BAL_API_RX_POLL_TIMEOUT         100000

/*****************************************************************************
 * Initialize the BAL Public API internal data structures
 *****************************************************************************/
bcmos_errno bcmbal_api_init(const char *balapi_mgmt_ip_port,
                            const char *core_mgmt_ip_port)
{
    bcmos_errno ret = BCM_ERR_OK;
    bcmos_msg_queue_parm msg_q_p = {};
    bcmos_task_parm task_p = {};

#ifdef ENABLE_LOG
    log_id_public_api = bcm_dev_log_id_register("BAL_API", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
    BUG_ON(log_id_public_api == DEV_LOG_INVALID_ID);
#endif

    do
    {
        STAILQ_INIT(&pending_req_list);

        ret = bcmos_mutex_create(&balapi_lock, 0, "bal_api");
        if (BCM_ERR_OK != ret)
        {
            BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API protection mutex\n");
            break;
        }

        /* Create BAL API RX management queue - the BAL Public API
         * exchanges management messages with the BAL core using this queue.
         */
        msg_q_p.name = "balapi_mgmt_q";
        if (NULL != balapi_mgmt_ip_port)
        {
            msg_q_p.local_ep_address = balapi_mgmt_ip_port;
            msg_q_p.remote_ep_address = NULL;
            msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;
        }
        else
        {
            msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_LOCAL;
        }
        ret = bcmos_msg_queue_create(&balapi_rsp_queue, &msg_q_p);
        if (BCM_ERR_OK != ret)
        {
            BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API mgmt queue\n");
            ret = BCM_ERR_INTERNAL;
            break;
        }
        p_balapi_rsp_queue = &balapi_rsp_queue;
#ifdef BAL_MONOLITHIC
        if (NULL == balapi_mgmt_ip_port)
            p_bal_core_to_api_queue = p_balapi_rsp_queue;
#endif

        /* Create queue for sending API requests to the core. Only do it if API and core interact via UDP
         */
        if (NULL != core_mgmt_ip_port)
        {
            msg_q_p.name = "balapi_to_core_q";
            msg_q_p.local_ep_address = NULL;
            msg_q_p.remote_ep_address = core_mgmt_ip_port;
            msg_q_p.ep_type = BCMOS_MSG_QUEUE_EP_UDP_SOCKET;

            ret = bcmos_msg_queue_create(&balapi_to_core_queue, &msg_q_p);
            if (BCM_ERR_OK != ret)
            {
                BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API mgmt queue\n");
                ret = BCM_ERR_INTERNAL;
                break;
            }
            p_balapi_to_core_queue = &balapi_to_core_queue;
        }

        /* Create BAL API RX thread */
        task_p.name = "ipc_api_rsp_rx_thread";
        task_p.priority = TASK_PRIORITY_IPC_RX;
        task_p.handler = _bal_ipc_api_rx_handler;
        task_p.data = (long)p_balapi_rsp_queue;

        ret = bcmos_task_create(&api_rsp_rx_thread, &task_p);
        if (ret)
        {
            BCM_LOG(ERROR, log_id_public_api, "Couldn't create BAL API response RX thread\n");
            break;
        }

        /*
         * Initialize the BAL Public API backend worker and rx threads.  These
         * threads are used to receive asynchronous indications from the core.
         */
        enable_bal_api_indications(balapi_mgmt_ip_port);

    }
    while(0);

    return ret;
}

/*****************************************************************************
 * Un-initialize the BAL Public API internal data structures
 *****************************************************************************/
bcmos_errno bcmbal_api_finish(void)
{
    bcmos_task_destroy(&api_rsp_rx_thread);
    bcmos_msg_queue_destroy(&balapi_rsp_queue);
    if (p_balapi_to_core_queue == &balapi_to_core_queue)
        bcmos_msg_queue_destroy(&balapi_to_core_queue);

    bal_api_indications_finish();

    return BCM_ERR_OK;
}

/* Find pending request matching response */
static bal_comm_msg_hdr *_bal_api_get_request_by_ex_id(uint32_t ex_id)
{
    bcmos_msg *req_msg, *tmp_msg;
    bal_comm_msg_hdr *comm_hdr = NULL;

    STAILQ_FOREACH_SAFE(req_msg, &pending_req_list, next, tmp_msg)
    {
        comm_hdr = bcmbal_bal_hdr_get_by_bcmos_hdr(req_msg);
        if (comm_hdr->ex_id == ex_id)
        {
            STAILQ_REMOVE(&pending_req_list, req_msg, bcmos_msg, next);
            break;
        }
    }
    return req_msg ? comm_hdr : NULL;
}

/* Check if any pending request timed out */
static void _bal_api_check_req_timeout(void)
{
    bcmos_msg *req_msg, *tmp_msg;
    bal_comm_msg_hdr *comm_hdr;
    bcmbal_obj *req_obj;
    uint32_t ts = bcmos_timestamp();

    STAILQ_FOREACH_SAFE(req_msg, &pending_req_list, next, tmp_msg)
    {
        comm_hdr = bcmbal_bal_hdr_get_by_bcmos_hdr(req_msg);
        if (ts - comm_hdr->timestamp >= BCMBAL_MSG_TIMEOUT_1_SEC)
        {
            STAILQ_REMOVE(&pending_req_list, req_msg, bcmos_msg, next);
            req_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(comm_hdr);
            /* Release pending API call */
            req_obj->status = BCM_ERR_TIMEOUT;
            BCM_LOG(DEBUG, log_id_public_api, "Timing out request %p\n", comm_hdr);
            bcmos_sem_post(&comm_hdr->sem);
        }
    }
}

/* API response handler */
static int _bal_ipc_api_rx_handler(long data)
{
    static uint32_t last_timeout_check_ts;
    bcmos_msg_queue *rxq = (bcmos_msg_queue *)data;
    bcmos_task *my_task = bcmos_task_current();
    bcmos_msg *msg;
    bcmos_errno ret = BCM_ERR_OK;
    uint32_t ex_id;
    bal_comm_msg_hdr *req;
    bcmbal_obj *req_obj;

    last_timeout_check_ts = bcmos_timestamp();
    while (!my_task->destroy_request)
    {
        /* Wait for response */
        msg = NULL;
        req = NULL;

        ret = bcmos_msg_recv(rxq, BAL_API_RX_POLL_TIMEOUT, &msg);
        if(BCM_ERR_OK != ret && BCM_ERR_TIMEOUT != ret)
        {
            BCM_LOG(ERROR, log_id_public_api,
                "error during bcmos_msg_recv (error:%s)\n", bcmos_strerror(ret));
        }

        /* Peek exchange id */
        if (msg)
        {
            ret = bcmbal_bal_msg_peek_ex_id(msg, &ex_id);
            if(BCM_ERR_OK != ret)
            {
                BCM_LOG(ERROR, log_id_public_api,
                    "bad message. Can't find exchange id (error:%s)\n", bcmos_strerror(ret));
                bcmos_msg_free(msg);
                msg = NULL;
            }
            else
            {
                BCM_LOG(DEBUG, log_id_public_api, "Received message with ex_id=%u\n", ex_id);
            }
        }

        /* Now find pending request and also check if any pending request(s) timed out */
        bcmos_mutex_lock(&balapi_lock);
        if (msg)
        {
            req = _bal_api_get_request_by_ex_id(ex_id);
            if (NULL == req)
            {
                BCM_LOG(ERROR, log_id_public_api,
                    "Request with ex_id=%u is not found. Probably expired. Response discarded\n", ex_id);
            }
            else
            {
                BCM_LOG(DEBUG, log_id_public_api, "Found request %p\n", req);
            }
        }
        if (bcmos_timestamp() - last_timeout_check_ts >= BCMBAL_MSG_TIMEOUT_1_SEC)
        {
            _bal_api_check_req_timeout();
            last_timeout_check_ts = bcmos_timestamp();
        }
        bcmos_mutex_unlock(&balapi_lock);

        /* Got a message. Now unpack it */
        if (req)
        {
            req_obj = (bcmbal_obj *)bcmbal_payload_ptr_get(req);
            ret = bcmbal_obj_msg_unpack(msg, &req);
            if (BCM_ERR_OK != ret)
            {
                BCM_LOG(ERROR, log_id_public_api, "Error during message unpack: %s\n", bcmos_strerror(ret));
                req_obj->status = ret;
            }
            /* Release pending API */
            BCM_LOG(DEBUG, log_id_public_api, "Posting request semaphore for %p\n", req);
            bcmos_sem_post(&req->sem);
        }

        if (msg)
            bcmos_msg_free(msg); /* release packed message. It is no longer needed */
    }

    my_task->destroyed = BCMOS_TRUE;

    return (BCM_ERR_OK == ret) ? 0 : -EINVAL;
}

static bcmbal_mgmt_oper_id _bcmbal_obj_to_oper_id(const bcmbal_obj *objinfo)
{
    if (objinfo->group == BCMBAL_MGT_GROUP_STAT)
    {
        return BCMBAL_MGMT_OPER_ID_GET_STATS;
    }
    else if ((objinfo->type & BCMBAL_OBJ_MSG_TYPE_GET))
    {
        return BCMBAL_MGMT_OPER_ID_GET;
    }
    else if ((objinfo->type & BCMBAL_OBJ_MSG_TYPE_CLEAR))
    {
        return BCMBAL_MGMT_OPER_ID_CLEAR;
    }
    else
    {
        return BCMBAL_MGMT_OPER_ID_SET;
    }
}

#define BALAPI_OPER_TIMEOUT (30000000) /* 30 seconds */

static bcmos_errno _bcmbal_oper(bcmbal_obj *objinfo)
{
    bal_comm_msg_hdr *comm_hdr = bcmbal_bal_hdr_get(objinfo);
    bcmos_msg *os_msg;
    bcmos_errno ret = BCM_ERR_OK;

    /*
     * Send the message to the core for processing
     */

    /* Parameter checks */
    BUG_ON(NULL == objinfo);

    /* Check the magic number to be sure that the object has been properly initialized */
    if(BCMBAL_OBJ_INIT_VAL != objinfo->obj_init_val)
    {
        BCM_LOG(ERROR, log_id_public_api, 
                "Object has not been initialized: must use a BCMBAL INIT macro on the object before calling the BAL API\n");
        return BCM_ERR_PARM;
    }

    ret = bcmos_sem_create(&comm_hdr->sem, 0, 0, "api_req");
    if (ret)
    {
        BCM_LOG(ERROR, log_id_public_api, "Can't create semaphore: %s\n", bcmos_strerror(ret));
        /* return here. We don't want to destroy semaphore that wasn't created */
        return ret;
    }

    do
    {
        bcmbal_msg_hdr_set(objinfo,
                           BCMBAL_MGMT_MSG,
                           BAL_MSG_TYPE_REQ,
                           BAL_SUBSYSTEM_PUBLIC_API,
                           objinfo->obj_type,
                           _bcmbal_obj_to_oper_id(objinfo),
                           0);

        BCM_LOG(DEBUG, log_id_public_api, "about to send %p\n", objinfo);

        bcmos_mutex_lock(&balapi_lock);
        bcmbal_ex_id_set(objinfo, ++balapi_exchange_id);
        os_msg = bcmbal_bcmos_hdr_get(objinfo);
        STAILQ_INSERT_TAIL(&pending_req_list, os_msg, next);
        bcmos_mutex_unlock(&balapi_lock);

        if (BCM_ERR_OK != (ret = bcmbal_msg_send(p_balapi_to_core_queue, objinfo, BCMOS_MSG_SEND_NO_FREE_ON_ERROR)))
        {
            BCM_LOG(ERROR, log_id_public_api, "message send failed with error: %s\n", bcmos_strerror(ret));
            break;
        }
        BCM_LOG(DEBUG, log_id_public_api, "REQ message sent to core\n");

        /*
         * We've sent the message to the core, now, wait for the response (or timeout)
         */
        ret = bcmos_sem_wait(&comm_hdr->sem, BALAPI_OPER_TIMEOUT);
        if (BCM_ERR_OK != ret)
        {
            BCM_LOG(ERROR, log_id_public_api, "rsp message receive for failed with error: %s\n",
                    bcmos_strerror(ret));
            break;
        }
        BCM_LOG(DEBUG, log_id_public_api, "RSP message received from core\n");

        if (BCM_ERR_OK != ret)
        {
            BCM_LOG(ERROR, log_id_public_api, "failed to process rsp msg\n");
            break;
        }

        if(BCM_ERR_OK != objinfo->status)
        {
            BCM_LOG(ERROR, log_id_public_api, "remote message command status is: %s\n",
                bcmos_strerror(objinfo->status));
        }

        /*
         * Pass the command status received from the core back to the caller
         */
        ret = objinfo->status;
    }
    while(0);

    bcmos_sem_destroy(&comm_hdr->sem);

    return ret;
}

/*****************************************************************************
 * BAL Public API Set (or modify) command.
 *****************************************************************************/
bcmos_errno bcmbal_cfg_set(bcmbal_cfg *objinfo)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(INFO, log_id_public_api, "BAL PUBLIC API - BCMBAL_SET\n");

    if(BCMBAL_OBJ_ID_PACKET == objinfo->hdr.obj_type)
    {
        BCM_LOG(ERROR, log_id_public_api, "unsupported object id detected %d\n", objinfo->hdr.obj_type);
        ret = BCM_ERR_NOT_SUPPORTED;

    }
    else
    {
        objinfo->hdr.type = BCMBAL_OBJ_MSG_TYPE_SET;
        ret = _bcmbal_oper(&objinfo->hdr);
    }

    return ret;
}

#define BCMBAL_MAX_PROXY_PACKET_SIZE  (1600)

/*****************************************************************************
 * BAL Public API Packet Send function.
 *****************************************************************************/
bcmos_errno bcmbal_pkt_send(bcmbal_dest dest,
                            const char *packet_to_send,
                            uint16_t packet_len)
{
    /* Convert the user packet into a BAL object */
    bcmbal_packet_cfg *p_packet_obj;
    bcmbal_packet_key key;
    bcmbal_u8_list_u32 pkt;
    bcmos_errno ret;

    BCM_LOG(INFO, log_id_public_api, "BAL PUBLIC API - BCMBAL_SEND to %s\n",
            (BCMBAL_DEST_TYPE_NNI == dest.type) ? "NNI" : "SUB-TERM");

    if(BCMBAL_MAX_PROXY_PACKET_SIZE < packet_len)
    {
        BCM_LOG(ERROR, log_id_public_api, "user packet length (%d) cannot be greater than %d\n",
                packet_len,
                BCMBAL_MAX_PROXY_PACKET_SIZE);

        return BCM_ERR_PARM;
    }

    BCM_LOG(INFO, log_id_public_api, "user packet first 8 bytes %02X%02X%02X%02X%02X%02X%02X%02X\n",
            packet_to_send[0], packet_to_send[1], packet_to_send[2], packet_to_send[3],
            packet_to_send[4], packet_to_send[5], packet_to_send[6], packet_to_send[7]);

    /* Set up the object key */
    key.packet_send_dest = dest;

    /* Allocate room for the packet object including the user packet */
    p_packet_obj = bcmos_calloc(sizeof(bcmbal_packet_cfg) + packet_len);

    BCMBAL_CFG_INIT(p_packet_obj, packet, key);

    /* Now fill in user packet data into the object */
    pkt.len = packet_len;
    pkt.val = (uint8_t *)&p_packet_obj[1];
    memcpy(pkt.val, packet_to_send, packet_len);

    BCMBAL_CFG_PROP_SET(p_packet_obj, packet, pkt, pkt);

    p_packet_obj->hdr.hdr.type = BCMBAL_OBJ_MSG_TYPE_SET; /* internally packet SEND is modeled as a config SET */
    ret = _bcmbal_oper(&(p_packet_obj->hdr.hdr));
    bcmos_free(p_packet_obj);

    return ret;
}

/*****************************************************************************
 * BAL Public API Get command.
 *****************************************************************************/
bcmos_errno bcmbal_cfg_get(bcmbal_cfg *objinfo)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(DEBUG, log_id_public_api, "BAL PUBLIC API - BCMBAL_GET\n");

    if(BCMBAL_OBJ_ID_PACKET == objinfo->hdr.obj_type)
    {
        BCM_LOG(ERROR, log_id_public_api, "unsupported object id detected %d\n", objinfo->hdr.obj_type);
        ret = BCM_ERR_NOT_SUPPORTED;

    }
    else
    {
        objinfo->hdr.type = BCMBAL_OBJ_MSG_TYPE_GET;
        ret = _bcmbal_oper(&(objinfo->hdr));
    }

    return ret;
}

/*****************************************************************************
 * BAL Public API Clear command.
 *****************************************************************************/
bcmos_errno bcmbal_cfg_clear(bcmbal_cfg *objinfo)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(INFO, log_id_public_api, "BAL PUBLIC API - BCMBAL_CLEAR\n");

    if(BCMBAL_OBJ_ID_PACKET == objinfo->hdr.obj_type)
    {
        BCM_LOG(ERROR, log_id_public_api, "unsupported object id detected %d\n", objinfo->hdr.obj_type);
        ret = BCM_ERR_NOT_SUPPORTED;

    }
    else
    {
        objinfo->hdr.type = BCMBAL_OBJ_MSG_TYPE_CLEAR;
        ret = _bcmbal_oper(&objinfo->hdr);
    }

    return ret;
}

/*****************************************************************************
 * @brief BAL Public API Get Stats command.
 *****************************************************************************/
bcmos_errno bcmbal_stat_get(bcmbal_stat *objinfo)
{

    /* Parameter checks */
    BUG_ON(NULL == objinfo);

    /*
     * @todo Finish the stats function
     */

    BCM_LOG(ERROR, log_id_public_api, "bal get stats API not supported\n");

    return BCM_ERR_NOT_SUPPORTED;
}

/*****************************************************************************
 * BAL Public API indication subscription.
 *****************************************************************************/
bcmos_errno bcmbal_subscribe_ind(bcmbal_cb_cfg *cb_cfg)
{

    bcmos_errno ret = BCM_ERR_OK;

    /*
     * The indication subscription function
     */
    BCM_LOG(DEBUG, log_id_public_api, "BAL indication subscription for type: %s (%d)\n",
            bcmbal_objtype_str(cb_cfg->obj_type), cb_cfg->obj_type);

    ret = _manage_api_ind_listener(IND_CB_SUBSCRIBE, cb_cfg);

    return ret;
}

/*****************************************************************************
 * BAL Public API indication un-subscription.
 *****************************************************************************/
bcmos_errno bcmbal_unsubscribe_ind(bcmbal_cb_cfg *cb_cfg)
{

    bcmos_errno ret = BCM_ERR_OK;

    BUG_ON(NULL == cb_cfg);

    /*
     * The indication subscription function
     */
    BCM_LOG(DEBUG, log_id_public_api, "BAL indication un-subscription for type: %s (%d)\n",
            bcmbal_objtype_str(cb_cfg->obj_type), cb_cfg->obj_type);

    ret = _manage_api_ind_listener(IND_CB_UNSUBSCRIBE, cb_cfg);

    return ret;
}

/*****************************************************************************/
/**
 * @brief A function to get the string representation of the interface type
 *
 * @param int_type          The interface type to get
 *
 * @returns const char *    A pointer to a string containing the interface type,
 *                          or "INVALID", if not a valid type.
 *
 *****************************************************************************/
const char *bcmbal_get_interface_type_str(bcmbal_intf_type int_type)
{
    const char *type_str;

    switch (int_type)
    {
        case(BCMBAL_INTF_TYPE_PON):
        {
            type_str = "pon";
        }
        break;

        case(BCMBAL_INTF_TYPE_NNI):
        {
            type_str = "nni";
        }
        break;

        default:
        {
            type_str = "INVALID";
        }
        break;

    }

    return type_str;
}


/*@}*/
