/**
 * @file tm_route_fwd.c
 *
 * @brief This file contains functions that helps to route
 *        the telemetry frame or data
 *
 * The functions provided in the file helps to route complete telemetry
 * frame or just the data based on the user mentioned routing parameters.
 * The routing parameters are stored in the local data structure.
 */
/*********************************************************************/
#include "tm_common.h"

/**
 * @brief This API searches for the routing table from the tm_fwd_head
 *        based on the da_id. If a routing table is found, it copies the
 *        routing information to the route_param of size equal to "size"
 *
 * @param[in] tm_fwd_head   : head node.
 * @param[in] da_id   : Destination Application id.
 * @param[out] route_param  : Pointer to the routing parameters
 * @param[in] size  : size of the routing table
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_SEARCH_ERROR if No routing parameter found for
 *          the da_id or TC_TM_LIB_NULL_PTR -> Error.
 */
static int8 tm_get_rout_table(node *tm_fwd_head, uint16 da_id,\
                                            void* route_param, size_t size);


/**
 * @brief This API copies the da_id, routing parameters (route_param) of size
 *        equals to "size" to the data structure. It is used to route the data
 *        if required based on the da_id.
 */
int8 tm_add_rout_table(node *tm_fwd_head, node *new_node,\
                                               uint16 da_id, void* route_param)
{
    int8 status = TC_TM_LIB_SEARCH_ERROR;;
    node *tmp = NULL;

    if((NULL == route_param) || (NULL == tm_fwd_head))
    {
        status = TC_TM_LIB_NULL_PTR;
    }
    else if(NULL == new_node)
    {
       // This call is made to populate head node
       tm_fwd_head->da_id = da_id;
       tm_fwd_head->route_param = route_param;
       tm_fwd_head->nxt = NULL;
       status =  TC_TM_LIB_OK;
    }
    else
    {
       // This call is made to populate new node
       tmp = tm_fwd_head;
       while(NULL != tmp)
       {
           if(NULL == tmp->nxt)
           {
               tmp->nxt = new_node;
               new_node->da_id = da_id;
               new_node->route_param = route_param;
               new_node->nxt = NULL;
               status =  TC_TM_LIB_OK;
               break;
           }
           tmp = tmp->nxt;
       }
    }

    return status;
}

/**
 * @brief This API searches for the routing table from the tm_fwd_head
 *        based on the da_id. If a routing table is found, it copies the
 *        routing information to the route_param of size equal to "size"
 */
static int8 tm_get_rout_table(node *tm_fwd_head, uint16 da_id,\
                                            void* route_param, size_t size)
{
    int8 status = TC_TM_LIB_SEARCH_ERROR;
    node *tmp_node = NULL;

    if(NULL == tm_fwd_head || NULL == route_param)
    {
        status = TC_TM_LIB_NULL_PTR;
    }
    else
    {
        tmp_node = tm_fwd_head;
        while(tmp_node != NULL)
        {
            if(tmp_node->da_id == da_id)
            {
                os_memcpy(route_param, tmp_node->route_param, size);
                status = TC_TM_LIB_OK;
                break;
            }
            else
            {
                tmp_node = tmp_node->nxt;
            }
        }
    }

    return status;
}

/**
 * @brief This API copies the routing parameters to the route_param
 *        based on the tm_orig->da_id. tm_fwd_add_rout_table ()
 *        need to invoked first to configure the routing table with da_id.
 */
int8 tm_route_pkt_hdrs(s_tm_frame *tm_orig, node *tm_fwd_head,\
                                                void* route_param, size_t size)
{
    int8 status;
    if((NULL != tm_orig) && (NULL != tm_fwd_head))
    {
        status = tm_get_rout_table(tm_fwd_head,
                                   tm_orig->da_id,
                                   route_param,
                                   size);
    }
    else
    {
        status = TC_TM_LIB_NULL_PTR;
    }
    return status;

}

/**
 * @brief This API copies the routing parameters to the route_param
 *        based on the tm_orig->da_id and tm_orig->data to the data param
 *        of size tm_orig->tm_len. tm_fwd_add_rout_table () need to be
 *        invoked first to configure the routing table with da_id.
 */
int8 tm_route_pkt(s_tm_frame *tm_orig, node *tm_fwd_head,\
                                   void* route_param, size_t size, uint8* data)
{
    int8 status;
    if((NULL != tm_orig) && (NULL != data) && (NULL != tm_fwd_head))
    {
        status = tm_get_rout_table(tm_fwd_head,
                                   tm_orig->da_id,
                                   route_param,
                                   size);
        os_memcpy(data, tm_orig->tm_data, tm_orig->tm_len);
    }
    else
    {
        status = TC_TM_LIB_NULL_PTR;
    }
    return status;

}
