/******************************************************************************
 *
 *  <: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_mac_util_db_apis.c
 *
 * @brief This file has the wrapper functions and the calls to database API functions. 
 * These wrapper functions are called by mac util code for DB operations.
 *
 * @addtogroup mac_util
 */

/*@{*/

#include <bal_mac_util.h>


/** 
 * @brief flow DB macros
 * */
/** @brief max number of flow types stored in the DB.
 *  @details for now upstream & downstream unicast flows only are stored in the flow DB 
 * */
#define MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES 2

/** @brief check if flow type key is valid */
#define MAC_UTIL_FLOW_DB_FLOW_TYPE_IS_VALID(_flow_type)                                        \
    ((_flow_type) >= BCMBAL_FLOW_TYPE_UPSTREAM &&                                              \
     (_flow_type) <= MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES)                                          \


/** 
 * @brief maps {flow Id, flow_type} Key pair to an {Index, sub-Index} pair to access a flow entry in the Array DB.
 * */
#define MAC_UTIL_FLOW_DB_FLOW_ID_TYPE2ARR_INDEX_SUB_INDEX(_flow_id, _flow_type, _index, _sub_index)                         \
    do                                                                                          \
    {                                                                                           \
        (_index) = (_sub_index) = 0;                                                            \
        if(MAC_UTIL_FLOW_DB_FLOW_ID_IS_VALID(_flow_id))                                         \
        {                                                                                       \
            if(MAC_UTIL_FLOW_DB_FLOW_TYPE_IS_VALID(_flow_type))                                 \
            {                                                                                   \
                (_index) = (_flow_id) - mac_util_flow_id_start_val+1;                           \
                (_sub_index) = (_flow_type) - 1;                                                \
            }                                                                                   \
        }                                                                                       \
    } while (0);                                                                            


/** @brief lookup an entry from the Array based on flow Id & type key pair */
#define MAC_UTIL_FLOW_DB_ENTRY_GET(_flow_id, _flow_type, _flow_entry)                           \
    do                                                                                          \
    {                                                                                           \
        (_flow_entry) = NULL;                                                                   \
        uint32_t _index, _sub_index;                                                            \
        MAC_UTIL_FLOW_DB_FLOW_ID_TYPE2ARR_INDEX_SUB_INDEX((_flow_id), (_flow_type), (_index), (_sub_index)); \
        if (!_index)                                                                            \
            break;                                                                              \
        _flow_entry = mac_util_db_flows_list[_index][_sub_index];                               \
    } while (0);                                                                               


/** @brief Get First non-NULL flow entry from the Array */
#define MAC_UTIL_FLOW_DB_ENTRY_GET_FIRST(_p_first)                                              \
    do                                                                                          \
    {                                                                                           \
        int _i, _j;                                                                             \
        for (_i=1; _i<=BAL_ACC_TERM_MAX_FLOWS; _i++)                                            \
        {                                                                                       \
            for (_j=0; _j<MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES; _j++)                                 \
            {                                                                                   \
                (_p_first) = mac_util_db_flows_list[_i][_j];                                    \
                if (_p_first)                                                                   \
                    break;                                                                      \
            }                                                                                   \
            if (_p_first)                                                                   \
                break;                                                                      \
        }                                                                                       \
    } while (0)                                                                                 


/** @brief Get Next non-NULL flow entry from the Array */
#define MAC_UTIL_FLOW_DB_ENTRY_GET_NEXT(_p_curr, _pp_next)                                      \
    do                                                                                          \
    {                                                                                           \
        uint32_t _i, _j, _curr_i, _curr_j;                                                                                 \
        *(_pp_next) = NULL;                                                                     \
        if (_p_curr)                                                                            \
        {                                                                                       \
            MAC_UTIL_FLOW_DB_FLOW_ID_TYPE2ARR_INDEX_SUB_INDEX(_p_curr->bal_flow_key.flow_id, _p_curr->bal_flow_key.flow_type, _curr_i, _curr_j);\
            for (_i = (_curr_j<MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES-1 ?_curr_i : _curr_i+1);         \
                     _i<=BAL_ACC_TERM_MAX_FLOWS;                                                \
                     _i++)                                                                      \
            {                                                                                   \
                for (_j= (_curr_j<MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES-1 ? _curr_j+1 : 0);           \
                        _j<MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES;                                     \
                        _j++)                                                                   \
                {                                                                               \
                    *(_pp_next) = mac_util_db_flows_list[_i][_j];                               \
                    if (*(_pp_next))                                                            \
                        break;                                                                  \
                }                                                                               \
                if (*(_pp_next))                                                                   \
                    break;                                                                      \
            }                                                                                   \
        }                                                                                       \
        else                                                                                    \
            break;                                                                              \
    } while (0)                                                                                 


/** @brief Set a flow entry in the Array */
#define MAC_UTIL_FLOW_DB_ENTRY_SET(_flow_id, _flow_type, _flow_entry, _rc)                      \
    do                                                                                          \
    {                                                                                           \
        uint32_t _index, _sub_index;                                                            \
        MAC_UTIL_FLOW_DB_FLOW_ID_TYPE2ARR_INDEX_SUB_INDEX((_flow_id), (_flow_type), (_index), (_sub_index)); \
        if (!_index)                                                                            \
        {                                                                                       \
            (_rc) = BCM_ERR_NULL;                                                               \
            break;                                                                              \
        }                                                                                       \
        mac_util_db_flows_list[_index][_sub_index] = (_flow_entry);                             \
    } while (0);                                                                                


/** 
 * @brief flow Id starting value that can used by SDN User application.
 * @details By default the starting flow Id is assumed to be 1.
 */
uint32_t mac_util_flow_id_start_val = 1;

/** 
 * @brief flow DB Array
 * @details This Array is for upstream & downstream flows and can store BAL_ACC_TERM_MAX_FLOWS flows.
 *          This array is indexed by BAL flow Id.
 *
 * @note First entry starts at index 1; (0 is not used).
 *
 * @note Upstream & Downstream flow types of a pair may use the same Flow Id.Hence there is a sub-array
 * of each of Flow Id entry. The sub array has upstream flow entry in index 0 and downstream at index 1.
 * Hence, a flow entry is accessible by the key pair {flowId, flowtype}.
 * */
static flow_list_entry *mac_util_db_flows_list[BAL_ACC_TERM_MAX_FLOWS + 1][MAC_UTIL_FLOW_DB_MAX_FLOW_TYPES];


/*****************************************************************************/
/** Flow DB wrapper Functions */

/** @todo in future with a new DB data structure, these wrapper functions would
 * be migrated to call those DB apis.
 */
/*****************************************************************************/

/**
 * @brief Allocate a new flow 
 *
 * @return  flow_list_entry  pointer to a new flow entry
 */
flow_list_entry *_mac_util_db_flow_alloc (void)
{
    flow_list_entry *p_flow = NULL;

    p_flow = bcmos_calloc(sizeof(flow_list_entry));
    /* bcmos_calloc already initializes the memory to 0 */

    return p_flow;
}

/**
 * @brief Free a flow (free the memory or return it to free pool) 
 *
 * @param pon_if            pon interface id
 * @param p_entry           pointer to a flow entry
 *
 * @returns bcmos_errno bcm errno
 *
 * @note it checks if the flow being freed is already removed from flow DB
 */
bcmos_errno _mac_util_db_flow_free (uint32_t pon_if, flow_list_entry *p_entry)
{
    bcmos_errno rc = BCM_ERR_OK;

    if (!IS_VALID_PON_IF(pon_if))
    {
        return BCM_ERR_PARM;
    }

    if (NULL == p_entry)
    {
        return BCM_ERR_PARM;
    }

    /* free the memory */
    bcmos_free(p_entry);

    return rc;
}

/**
 * @brief Add an already allocated flow to flow DB 
 *
 * @param pon_if            pon interface id
 * @param p_entry           pointer to a new flow entry
 *
 * @returns bcmos_errno bcm errno
 *
 * @todo in proper DB, it should check if the entry is already in the list or not
 */
bcmos_errno _mac_util_db_flow_add (uint32_t pon_if, flow_list_entry *p_entry)
{
    bcmos_errno rc = BCM_ERR_OK;

    if (!IS_VALID_PON_IF(pon_if))
        return BCM_ERR_PARM;

    if (!p_entry)
        return BCM_ERR_PARM;

    MAC_UTIL_FLOW_DB_ENTRY_SET(p_entry->bal_flow_key.flow_id, p_entry->bal_flow_key.flow_type, p_entry, rc);

    return rc;
}

/**
 * @brief Remove a flow entry from flow DB 
 *
 * @param pon_if            pon interface id
 * @param p_entry           pointer to a flow entry
 *
 * @returns bcmos_errno bcm errno
 *
 * @todo this API will  be ported to different DB when we have one
 */
bcmos_errno _mac_util_db_flow_remove (uint32_t pon_if, flow_list_entry *p_entry)
{
    bcmos_errno rc = BCM_ERR_OK;

    if (!IS_VALID_PON_IF(pon_if))
        return BCM_ERR_PARM;

    if (!p_entry)
        return BCM_ERR_PARM;

    MAC_UTIL_FLOW_DB_ENTRY_SET(p_entry->bal_flow_key.flow_id, p_entry->bal_flow_key.flow_type, NULL, rc);

    return rc;
}

/**
 * @brief Lookup a flow based on a flow id and pon if
 *
 * @param pon_if                pon interface id
 * @param p_flow_key            pointer to flow key
 *
 * @returns flow_list_entry     pointer a flow entry in list
 */
flow_list_entry *_mac_util_db_flow_get_w_flow_key (uint32_t pon_if, bcmbal_flow_key *p_flow_key)
{
    flow_list_entry *p_flow = NULL;

    if (!IS_VALID_PON_IF(pon_if))
    {
        return NULL;
    }

    MAC_UTIL_FLOW_DB_ENTRY_GET(p_flow_key->flow_id, p_flow_key->flow_type, p_flow);

    return p_flow;
}

/**
 * @brief get next flow based on flow id and pon_if
 *
 * @param pon_if            pon interface id
 * @param p_curr_entry   pointer to current flow entry
 * @param pp_next_entry  double pointer to next flow entry
 *
 * @returns  flow_list_entry  pointer to next flow entry in DB
 */
flow_list_entry *_mac_util_db_flow_get_next_w_flow_key (uint32_t pon_if, flow_list_entry *p_curr_entry, flow_list_entry **pp_next_entry)
{
    flow_list_entry *p_tmp_entry = p_curr_entry;

    if (!IS_VALID_PON_IF(pon_if))
    {
        BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
        return NULL;
    }

    /** @note this while loop is to continue to iterate through the DB until an entry with matching pon If is found */
    while (1)
    {
        if (NULL == p_tmp_entry)
        {
            /* get first flow */
            MAC_UTIL_FLOW_DB_ENTRY_GET_FIRST(p_tmp_entry);
            if (p_tmp_entry)
            {
                MAC_UTIL_FLOW_DB_ENTRY_GET_NEXT(p_tmp_entry, pp_next_entry);

                if (p_tmp_entry && (pon_if == p_tmp_entry->if_id))
                    return p_tmp_entry;
            }
            else
                break;  /* at the end of list */
        }
        else
        {
            if (NULL != *pp_next_entry)
            {
                p_tmp_entry = *pp_next_entry;
                MAC_UTIL_FLOW_DB_ENTRY_GET_NEXT(p_tmp_entry, pp_next_entry);

                if (pon_if == p_tmp_entry->if_id)
                    return p_tmp_entry;
            }
            else
                break;  /* at the end of list */
        }
    }

    return  NULL;
}


/**
 * @brief get next flow based on sub terminal id
 *
 * @param pon_if            pon interface id
 * @param sub_term_id       sub term id as the key
 * @param p_curr_entry      pointer to current flow entry
 * @param pp_next_entry     double pointer to next flow entry
 *
 * @returns  flow_list_entry  pointer to next flow entry  in DB
 * 
 */
flow_list_entry *_mac_util_db_flow_get_next_w_sub_term_id (uint32_t pon_if, uint32_t sub_term_id, 
													   flow_list_entry *p_curr_entry, flow_list_entry **pp_next_entry)
{
    flow_list_entry *p_tmp_entry = NULL;

    if (!IS_VALID_PON_IF(pon_if))
    {
        BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
        return NULL;
    }

    p_tmp_entry = _mac_util_db_flow_get_next_w_flow_key (pon_if, p_curr_entry, pp_next_entry);

    while (NULL != p_tmp_entry)
    {
        if (sub_term_id == p_tmp_entry->sub_term_id)
        {
            /* found sub_term  match */
            return p_tmp_entry;
        }
        /** @note passing tmp entry here because this is a getnext loop internal to this routine */
        p_tmp_entry = _mac_util_db_flow_get_next_w_flow_key (pon_if, p_tmp_entry, pp_next_entry);
    }

    return  NULL;
}

/**
 * @brief count of flows using a gem port and pon_if
 *
 * @param pon_if            pon interface id
 * @param gem_port_id       gem port id as the key
 * @param p_count           pointer to U32 to save count of flows using the same gem port
 *
 * @returns bcmos_errno bcm errno
 *
 */
bcmos_errno _mac_util_db_flow_count_w_gem (uint32_t pon_if, uint16_t gem_port_id, uint32_t *p_count)
{
    uint32_t count = 0;
    flow_list_entry *p_tmp_entry = NULL;
    void *p_rsc_mgr_curr_entry = NULL;
    void *p_rsc_mgr_next_entry = NULL;

    BUG_ON(NULL == p_count);

    if (!IS_VALID_PON_IF(pon_if))
    {
        BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
        return BCM_ERR_PARM;
    }

    p_tmp_entry = _mac_util_db_flow_get_next_w_gem (pon_if, gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
    while (NULL != p_tmp_entry)
    {
        count++;
        p_tmp_entry = _mac_util_db_flow_get_next_w_gem (pon_if, gem_port_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
    }

    *p_count = count;
    return BCM_ERR_OK;
}


/**
 * @brief get next flow based on gem and pon if
 *
 * @param pon_if            pon interface id
 * @param gem_port_id       gem port id as the key
 * @param **pp_rsc_mgr_curr_entry   double pointer to current entry in Rsrc Mgr Database
 * @param **pp_rsc_mgr_next_entry   double pointer to next entry in Rsrc Mgr Database
 *
 * @returns  flow_list_entry  pointer to next flow entry  in DB
 *
 * @note this queries resource mgr DB
 */
flow_list_entry *_mac_util_db_flow_get_next_w_gem (uint32_t pon_if, uint16_t gem_port_id, 
                                                    void **pp_rsc_mgr_curr_entry, void **pp_rsc_mgr_next_entry)
{
    flow_inst *p_core_flow_entry = NULL;
    flow_list_entry *p_flow_entry = NULL;

    if (!IS_VALID_PON_IF(pon_if))
    {
        BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
        return NULL;
    }

    p_core_flow_entry = rsc_mgr_gem_get_next_user_data (pon_if, gem_port_id, pp_rsc_mgr_curr_entry, pp_rsc_mgr_next_entry);

    while (NULL != p_core_flow_entry)
    {
        p_flow_entry = _mac_util_db_flow_get_w_flow_key(pon_if, &p_core_flow_entry->current_flow_info.key);
        if (p_flow_entry)
        {
            /* found gem match */
            return p_flow_entry;
        }
        p_core_flow_entry = rsc_mgr_gem_get_next_user_data (pon_if, gem_port_id, pp_rsc_mgr_curr_entry, pp_rsc_mgr_next_entry);
    }

    return  NULL;
}

/**
 * @brief count of flows using an alloc id and pon if
 *
 * @param pon_if            pon interface id
 * @param alloc_id          alloc id as the key
 * @param p_count           pointer to U32 that save the count of flows using the same alloc id
 *
 * @returns bcmos_errno bcm errno
 */
bcmos_errno _mac_util_db_flow_count_w_alloc_id (uint32_t pon_if, uint16_t alloc_id, uint32_t *p_count)
{
    uint32_t count = 0;
    flow_list_entry *p_tmp_entry = NULL;
    void *p_rsc_mgr_curr_entry = NULL;
    void *p_rsc_mgr_next_entry = NULL;

    BUG_ON( NULL == p_count);

    if (!IS_VALID_PON_IF(pon_if))
    {
        BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
        return BCM_ERR_PARM;
    }

    p_tmp_entry = _mac_util_db_flow_get_next_w_alloc_id (pon_if, alloc_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
    while (NULL != p_tmp_entry)
    {
        count++;
        p_tmp_entry = _mac_util_db_flow_get_next_w_alloc_id (pon_if, alloc_id, &p_rsc_mgr_curr_entry, &p_rsc_mgr_next_entry);
    }

    *p_count = count;
    return BCM_ERR_OK;
}

/**
 * @brief get next flow based on upstream alloc id and pon if
 *
 * @param pon_if            pon interface id
 * @param alloc_id          alloc id as the key
 * @param **pp_rsc_mgr_curr_entry   double pointer to current entry in Rsrc Mgr Database
 * @param **pp_rsc_mgr_next_entry   double pointer to next entry in Rsrc Mgr Database
 *
 * @returns  flow_list_entry  pointer to next flow entry  in DB
 *
 * @note this queries resource mgr DB
 */
flow_list_entry *_mac_util_db_flow_get_next_w_alloc_id (uint32_t pon_if, uint16_t alloc_id,
                                                        void **pp_rsc_mgr_curr_entry, void **pp_rsc_mgr_next_entry)
{
    flow_inst *p_core_flow_entry = NULL;
    flow_list_entry *p_flow_entry = NULL;

    if (!IS_VALID_PON_IF(pon_if))
    {
        BCM_LOG(ERROR,log_id_mac_util,"Invalid pon_if %d !", pon_if);
        return NULL;
    }

    p_core_flow_entry = rsc_mgr_alloc_id_get_next_user_data(pon_if, alloc_id, pp_rsc_mgr_curr_entry, pp_rsc_mgr_next_entry);

    while (NULL != p_core_flow_entry)
    {
        p_flow_entry = _mac_util_db_flow_get_w_flow_key(pon_if, &p_core_flow_entry->current_flow_info.key);
        if (p_flow_entry)
        {
            /* found alloc id match */
            return p_flow_entry;
        }
        p_core_flow_entry = rsc_mgr_alloc_id_get_next_user_data(pon_if, alloc_id, pp_rsc_mgr_curr_entry, pp_rsc_mgr_next_entry);
    }

    return  NULL;
}

/*@}*/
