/* Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright notice, this
 *      list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *
 *   3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *      contributors may be used to endorse or promote products derived from
 *      this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

/**
 * @file
 *   This file implements procedures to set pending bit and 802.15.4-2015 information
 *   elements in nRF 802.15.4 radio driver.
 *
 */

#include "nrf_802154_ack_data.h"

#include <assert.h>
#include <string.h>

#include "mac_features/nrf_802154_frame_parser.h"
#include "nrf_802154_config.h"
#include "nrf_802154_const.h"
#include "nrf_802154_types.h"

/// Maximum number of Short Addresses of nodes for which there is ACK data to set.
#define NUM_SHORT_ADDRESSES    NRF_802154_PENDING_SHORT_ADDRESSES
/// Maximum number of Extended Addresses of nodes for which there is ACK data to set.
#define NUM_EXTENDED_ADDRESSES NRF_802154_PENDING_EXTENDED_ADDRESSES

/// Structure representing pending bit setting variables.
typedef struct
{
    bool     enabled;                                                      /// If setting pending bit is enabled.
    uint8_t  short_addr[NUM_SHORT_ADDRESSES][SHORT_ADDRESS_SIZE];          /// Array of short addresses of nodes for which there is pending data in the buffer.
    uint8_t  extended_addr[NUM_EXTENDED_ADDRESSES][EXTENDED_ADDRESS_SIZE]; /// Array of extended addresses of nodes for which there is pending data in the buffer.
    uint32_t num_of_short_addr;                                            /// Current number of short addresses of nodes for which there is pending data in the buffer.
    uint32_t num_of_ext_addr;                                              /// Current number of extended addresses of nodes for which there is pending data in the buffer.
} pending_bit_arrays_t;

// Structure representing a single IE record.
typedef struct
{
    uint8_t p_data[NRF_802154_MAX_ACK_IE_SIZE]; /// Pointer to IE data buffer.
    uint8_t len;                                /// Length of the buffer.
} ie_data_t;

// Structure representing IE records sent in an ACK message to a given short address.
typedef struct
{
    uint8_t   addr[SHORT_ADDRESS_SIZE]; /// Short address of peer node.
    ie_data_t ie_data;                  /// Pointer to IE records.
} ack_short_ie_data_t;

// Structure representing IE records sent in an ACK message to a given extended address.
typedef struct
{
    uint8_t   addr[EXTENDED_ADDRESS_SIZE]; /// Extended address of peer node.
    ie_data_t ie_data;                     /// Pointer to IE records.
} ack_ext_ie_data_t;

// Structure representing IE data setting variables.
typedef struct
{
    ack_short_ie_data_t short_data[NUM_SHORT_ADDRESSES];  /// Array of short addresses and IE records sent to these addresses.
    ack_ext_ie_data_t   ext_data[NUM_EXTENDED_ADDRESSES]; /// Array of extended addresses and IE records sent to these addresses.
    uint32_t            num_of_short_data;                /// Current number of short addresses stored in @p short_data.
    uint32_t            num_of_ext_data;                  /// Current number of extended addresses stored in @p ext_data.
} ie_arrays_t;

// TODO: Combine below arrays to perform binary search only once per Ack generation.
static pending_bit_arrays_t m_pending_bit;
static ie_arrays_t          m_ie;

/***************************************************************************************************
 * @section Array handling helper functions
 **************************************************************************************************/

/**
 * @brief Compare two extended addresses.
 *
 * @param[in]  p_first_addr     Pointer to a first address that should be compared.
 * @param[in]  p_second_addr    Pointer to a second address that should be compared.
 *
 * @retval -1  First address is less than the second address.
 * @retval  0  First address is equal to the second address.
 * @retval  1  First address is greater than the second address.
 */
static int8_t extended_addr_compare(const uint8_t * p_first_addr, const uint8_t * p_second_addr)
{
    uint32_t first_addr;
    uint32_t second_addr;

    // Compare extended address in two steps to prevent unaligned access error.
    for (uint32_t i = 0; i < EXTENDED_ADDRESS_SIZE / sizeof(uint32_t); i++)
    {
        first_addr  = *(uint32_t *)(p_first_addr + (i * sizeof(uint32_t)));
        second_addr = *(uint32_t *)(p_second_addr + (i * sizeof(uint32_t)));

        if (first_addr < second_addr)
        {
            return -1;
        }
        else if (first_addr > second_addr)
        {
            return 1;
        }
    }

    return 0;
}

/**
 * @brief Compare two short addresses.
 *
 * @param[in]  p_first_addr     Pointer to a first address that should be compared.
 * @param[in]  p_second_addr    Pointer to a second address that should be compared.
 *
 * @retval -1  First address is less than the second address.
 * @retval  0  First address is equal to the second address.
 * @retval  1  First address is greater than the second address.
 */
static int8_t short_addr_compare(const uint8_t * p_first_addr, const uint8_t * p_second_addr)
{
    uint16_t first_addr  = *(uint16_t *)(p_first_addr);
    uint16_t second_addr = *(uint16_t *)(p_second_addr);

    if (first_addr < second_addr)
    {
        return -1;
    }
    else if (first_addr > second_addr)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

/**
 * @brief Compare two addresses.
 *
 * @param[in]  p_first_addr     Pointer to a first address that should be compared.
 * @param[in]  p_second_addr    Pointer to a second address that should be compared.
 * @param[in]  extended         Indication if @p p_first_addr and @p p_second_addr are extended or short addresses.
 *
 * @retval -1  First address is less than the second address.
 * @retval  0  First address is equal to the second address.
 * @retval  1  First address is greater than the second address.
 */
static int8_t addr_compare(const uint8_t * p_first_addr,
                           const uint8_t * p_second_addr,
                           bool            extended)
{
    if (extended)
    {
        return extended_addr_compare(p_first_addr, p_second_addr);
    }
    else
    {
        return short_addr_compare(p_first_addr, p_second_addr);
    }
}

/**
 * @brief Perform a binary search for an address in a list of addresses.
 *
 * @param[in]  p_addr           Pointer to an address that is searched for.
 * @param[in]  p_addr_array     Pointer to a list of addresses to be searched.
 * @param[out] p_location       If the address @p p_addr appears in the list, this is its index in the address list.
 *                              Otherwise, it is the index which @p p_addr would have if it was placed in the list
 *                              (ascending order assumed).
 * @param[in]  extended         Indication if @p p_addr is an extended or a short addresses.
 *
 * @retval true   Address @p p_addr is in the list.
 * @retval false  Address @p p_addr is not in the list.
 */
static bool addr_binary_search(const uint8_t * p_addr,
                               const uint8_t * p_addr_array,
                               uint32_t      * p_location,
                               uint8_t         data_type,
                               bool            extended)
{
    uint32_t addr_array_len = 0;
    uint8_t  entry_size     = 0;

    switch (data_type)
    {
        case NRF_802154_ACK_DATA_PENDING_BIT:
            entry_size     = extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE;
            addr_array_len = extended ?
                             m_pending_bit.num_of_ext_addr : m_pending_bit.num_of_short_addr;
            break;

        case NRF_802154_ACK_DATA_IE:
            entry_size     = extended ? sizeof(ack_ext_ie_data_t) : sizeof(ack_short_ie_data_t);
            addr_array_len = extended ? m_ie.num_of_ext_data : m_ie.num_of_short_data;
            break;

        default:
            assert(false);
            break;
    }

    // The actual algorithm
    int32_t  low      = 0;
    uint32_t midpoint = 0;
    int32_t  high     = addr_array_len;

    while (high >= low)
    {
        midpoint = (uint32_t)(low + (high - low) / 2);

        if (midpoint >= addr_array_len)
        {
            break;
        }

        switch (addr_compare(p_addr, p_addr_array + entry_size * midpoint, extended))
        {
            case -1:
                high = (int32_t)(midpoint - 1);
                break;

            case 0:
                *p_location = midpoint;
                return true;

            case 1:
                low = (int32_t)(midpoint + 1);
                break;

            default:
                break;
        }
    }

    /* If in the last iteration of the loop the last case was utilized, it means that the midpoint
     * found by the algorithm is less than the address to be added. The midpoint should be therefore
     * shifted to the next position. As a simplified example, a { 1, 3, 4 } array can be considered.
     * Suppose that a number equal to 2 is about to be added to the array. At the beginning of the
     * last iteration, midpoint is equal to 1 and low and high are equal to 0. Midpoint is then set
     * to 0 and with last case being utilized, low is set to 1. However, midpoint equal to 0 is
     * incorrect, as in the last iteration first element of the array proves to be less than the
     * element to be added to the array. With the below code, midpoint is then shifted to 1. */
    if ((uint32_t)low == midpoint + 1)
    {
        midpoint++;
    }

    *p_location = midpoint;
    return false;
}

/**
 * @brief Find an address in a list of addresses.
 *
 * @param[in]  p_addr           Pointer to an address that is searched for.
 * @param[out] p_location       If the address @p p_addr appears in the list, this is its index in the address list.
 *                              Otherwise, it is the index which @p p_addr would have if it was placed in the list
 *                              (ascending order assumed).
 * @param[in]  extended         Indication if @p p_addr is an extended or a short addresses.
 *
 * @retval true   Address @p p_addr is in the list.
 * @retval false  Address @p p_addr is not in the list.
 */
static bool addr_index_find(const uint8_t * p_addr,
                            uint32_t      * p_location,
                            uint8_t         data_type,
                            bool            extended)
{
    uint8_t * p_addr_array;
    bool      valid_data_type = true;

    switch (data_type)
    {
        case NRF_802154_ACK_DATA_PENDING_BIT:
            p_addr_array = extended ? (uint8_t *)m_pending_bit.extended_addr :
                           (uint8_t *)m_pending_bit.short_addr;
            break;

        case NRF_802154_ACK_DATA_IE:
            p_addr_array = extended ? (uint8_t *)m_ie.ext_data : (uint8_t *)m_ie.short_data;
            break;

        default:
            valid_data_type = false;
            assert(false);
            break;
    }

    if (!valid_data_type)
    {
        return false;
    }

    return addr_binary_search(p_addr, p_addr_array, p_location, data_type, extended);
}

/**
 * @brief Add an address to the address list in ascending order.
 *
 * @param[in]  p_addr           Pointer to the address to be added.
 * @param[in]  location         Index of the location where @p p_addr should be added.
 * @param[in]  extended         Indication if @p p_addr is an extended or a short addresses.
 *
 * @retval true   Address @p p_addr has been added to the list successfully.
 * @retval false  Address @p p_addr could not be added to the list.
 */
static bool addr_add(const uint8_t * p_addr, uint32_t location, uint8_t data_type, bool extended)
{
    uint32_t * p_addr_array_len;
    uint32_t   max_addr_array_len;
    uint8_t  * p_addr_array;
    uint8_t    entry_size;
    bool       valid_data_type = true;

    switch (data_type)
    {
        case NRF_802154_ACK_DATA_PENDING_BIT:
            if (extended)
            {
                p_addr_array       = (uint8_t *)m_pending_bit.extended_addr;
                max_addr_array_len = NUM_EXTENDED_ADDRESSES;
                p_addr_array_len   = &m_pending_bit.num_of_ext_addr;
                entry_size         = EXTENDED_ADDRESS_SIZE;
            }
            else
            {
                p_addr_array       = (uint8_t *)m_pending_bit.short_addr;
                max_addr_array_len = NUM_SHORT_ADDRESSES;
                p_addr_array_len   = &m_pending_bit.num_of_short_addr;
                entry_size         = SHORT_ADDRESS_SIZE;
            }
            break;

        case NRF_802154_ACK_DATA_IE:
            if (extended)
            {
                p_addr_array       = (uint8_t *)m_ie.ext_data;
                max_addr_array_len = NUM_EXTENDED_ADDRESSES;
                p_addr_array_len   = &m_ie.num_of_ext_data;
                entry_size         = sizeof(ack_ext_ie_data_t);
            }
            else
            {
                p_addr_array       = (uint8_t *)m_ie.short_data;
                max_addr_array_len = NUM_SHORT_ADDRESSES;
                p_addr_array_len   = &m_ie.num_of_short_data;
                entry_size         = sizeof(ack_short_ie_data_t);
            }
            break;

        default:
            valid_data_type = false;
            assert(false);
            break;
    }

    if (!valid_data_type || (*p_addr_array_len == max_addr_array_len))
    {
        return false;
    }

    memmove(p_addr_array + entry_size * (location + 1),
            p_addr_array + entry_size * (location),
            (*p_addr_array_len - location) * entry_size);

    memcpy(p_addr_array + entry_size * location,
           p_addr,
           extended ? EXTENDED_ADDRESS_SIZE : SHORT_ADDRESS_SIZE);

    (*p_addr_array_len)++;

    return true;
}

/**
 * @brief Remove an address from the address list keeping it in ascending order.
 *
 * @param[in]  location     Index of the element to be removed from the list.
 * @param[in]  extended     Indication if address to remove is an extended or a short address.
 *
 * @retval true   Address @p p_addr has been removed from the list successfully.
 * @retval false  Address @p p_addr could not removed from the list.
 */
static bool addr_remove(uint32_t location, uint8_t data_type, bool extended)
{
    uint32_t * p_addr_array_len;
    uint8_t  * p_addr_array;
    uint8_t    entry_size;
    bool       valid_data_type = true;

    switch (data_type)
    {
        case NRF_802154_ACK_DATA_PENDING_BIT:
            if (extended)
            {
                p_addr_array     = (uint8_t *)m_pending_bit.extended_addr;
                p_addr_array_len = &m_pending_bit.num_of_ext_addr;
                entry_size       = EXTENDED_ADDRESS_SIZE;
            }
            else
            {
                p_addr_array     = (uint8_t *)m_pending_bit.short_addr;
                p_addr_array_len = &m_pending_bit.num_of_short_addr;
                entry_size       = SHORT_ADDRESS_SIZE;
            }
            break;

        case NRF_802154_ACK_DATA_IE:
            if (extended)
            {
                p_addr_array     = (uint8_t *)m_ie.ext_data;
                p_addr_array_len = &m_ie.num_of_ext_data;
                entry_size       = sizeof(ack_ext_ie_data_t);
            }
            else
            {
                p_addr_array     = (uint8_t *)m_ie.short_data;
                p_addr_array_len = &m_ie.num_of_short_data;
                entry_size       = sizeof(ack_short_ie_data_t);
            }
            break;

        default:
            valid_data_type = false;
            assert(false);
            break;
    }

    if (!valid_data_type || (*p_addr_array_len == 0))
    {
        return false;
    }

    memmove(p_addr_array + entry_size * location,
            p_addr_array + entry_size * (location + 1),
            (*p_addr_array_len - location - 1) * entry_size);

    (*p_addr_array_len)--;

    return true;
}

static void ie_data_add(uint32_t location, bool extended, const uint8_t * p_data, uint8_t data_len)
{
    if (extended)
    {
        memcpy(m_ie.ext_data[location].ie_data.p_data, p_data, data_len);
        m_ie.ext_data[location].ie_data.len = data_len;
    }
    else
    {
        memcpy(m_ie.short_data[location].ie_data.p_data, p_data, data_len);
        m_ie.short_data[location].ie_data.len = data_len;
    }
}

/***************************************************************************************************
 * @section Public API
 **************************************************************************************************/

void nrf_802154_ack_data_init(void)
{
    memset(&m_pending_bit, 0, sizeof(m_pending_bit));
    memset(&m_ie, 0, sizeof(m_ie));

    m_pending_bit.enabled = true;
}

void nrf_802154_ack_data_enable(bool enabled)
{
    m_pending_bit.enabled = enabled;
}

bool nrf_802154_ack_data_for_addr_set(const uint8_t * p_addr,
                                      bool            extended,
                                      uint8_t         data_type,
                                      const void    * p_data,
                                      uint8_t         data_len)
{
    uint32_t location = 0;

    if (addr_index_find(p_addr, &location, data_type, extended) ||
        addr_add(p_addr, location, data_type, extended))
    {
        if (data_type == NRF_802154_ACK_DATA_IE)
        {
            ie_data_add(location, extended, p_data, data_len);
        }

        return true;
    }
    else
    {
        return false;
    }
}

bool nrf_802154_ack_data_for_addr_clear(const uint8_t * p_addr, bool extended, uint8_t data_type)
{
    uint32_t location = 0;

    if (addr_index_find(p_addr, &location, data_type, extended))
    {
        return addr_remove(location, data_type, extended);
    }
    else
    {
        return false;
    }
}

void nrf_802154_ack_data_reset(bool extended, uint8_t data_type)
{
    switch (data_type)
    {
        case NRF_802154_ACK_DATA_PENDING_BIT:
            if (extended)
            {
                m_pending_bit.num_of_ext_addr = 0;
            }
            else
            {
                m_pending_bit.num_of_short_addr = 0;
            }
            break;

        case NRF_802154_ACK_DATA_IE:
            if (extended)
            {
                m_ie.num_of_ext_data = 0;
            }
            else
            {
                m_ie.num_of_short_data = 0;
            }
            break;

        default:
            break;
    }
}

bool nrf_802154_ack_data_pending_bit_should_be_set(const uint8_t * p_frame)
{
    bool            extended;
    uint32_t        location;
    const uint8_t * p_src_addr = nrf_802154_frame_parser_src_addr_get(p_frame, &extended);

    // The pending bit is set by default.
    if (!m_pending_bit.enabled || NULL == p_src_addr)
    {
        return true;
    }

    return addr_index_find(p_src_addr, &location, NRF_802154_ACK_DATA_PENDING_BIT, extended);
}

const uint8_t * nrf_802154_ack_data_ie_get(const uint8_t * p_src_addr,
                                           bool            src_addr_extended,
                                           uint8_t       * p_ie_length)
{
    uint32_t location;

    if (NULL == p_src_addr)
    {
        return NULL;
    }

    if (addr_index_find(p_src_addr, &location, NRF_802154_ACK_DATA_IE, src_addr_extended))
    {
        if (src_addr_extended)
        {
            *p_ie_length = m_ie.ext_data[location].ie_data.len;
            return m_ie.ext_data[location].ie_data.p_data;
        }
        else
        {
            *p_ie_length = m_ie.short_data[location].ie_data.len;
            return m_ie.short_data[location].ie_data.p_data;
        }
    }
    else
    {
        *p_ie_length = 0;
        return NULL;
    }
}
