/*
 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <platform/ESP32/route_hook/ESP32RouteTable.h>

#include <string.h>

#include "esp_err.h"
#include "esp_log.h"
#include "lwip/ip6_addr.h"
#include "lwip/netif.h"
#include "lwip/timeouts.h"

#define MAX_RIO_TIMEOUT UINT32_MAX / (1000 * 4) // lwIP defined reasonable timeout value

static esp_route_entry_t * s_route_entries = NULL;

static esp_route_entry_t * find_route_entry(const esp_route_entry_t * route_entry)
{
    for (esp_route_entry_t * iter = s_route_entries; iter != NULL; iter = iter->next)
    {
        if (iter->netif == route_entry->netif && iter->prefix_length == route_entry->prefix_length &&
            memcmp(iter->gateway.addr, route_entry->gateway.addr, sizeof(route_entry->gateway.addr)) == 0 &&
            memcmp(iter->prefix.addr, route_entry->prefix.addr, route_entry->prefix_length / 8) == 0)
        {
            return iter;
        }
    }

    return NULL;
}

static esp_err_t remove_route_entry(esp_route_entry_t * route_entry)
{
    if (s_route_entries == route_entry)
    {
        s_route_entries = s_route_entries->next;
        free(route_entry);
        return ESP_OK;
    }

    for (esp_route_entry_t * iter = s_route_entries; iter != NULL; iter = iter->next)
    {
        if (iter->next == route_entry)
        {
            iter->next = route_entry->next;
            free(route_entry);
            return ESP_OK;
        }
    }

    ESP_LOGW(TAG, "The given route entry is not found");
    return ESP_ERR_NOT_FOUND;
}

static void route_timeout_handler(void * arg)
{
    esp_route_entry_t * route = (esp_route_entry_t *) arg;

    remove_route_entry(route);
}

esp_route_entry_t * esp_route_table_add_route_entry(const esp_route_entry_t * route_entry)
{
    if (route_entry == NULL || (route_entry->lifetime_seconds > MAX_RIO_TIMEOUT && route_entry->lifetime_seconds != UINT32_MAX))
    {
        return NULL;
    }

    esp_route_entry_t * entry = find_route_entry(route_entry);

    if (entry == NULL)
    {
        entry = (esp_route_entry_t *) malloc(sizeof(esp_route_entry_t));
        if (entry == NULL)
        {
            ESP_LOGW(TAG, "Cannot allocate route entry");
            return NULL;
        }

        entry->netif   = route_entry->netif;
        entry->gateway = route_entry->gateway;
        ip6_addr_assign_zone(&entry->gateway, IP6_UNICAST, entry->netif);
        entry->prefix        = route_entry->prefix;
        entry->prefix_length = route_entry->prefix_length;

        entry->next     = s_route_entries;
        s_route_entries = entry;
    }
    else
    {
        sys_untimeout(route_timeout_handler, entry);
    }
    entry->preference       = route_entry->preference;
    entry->lifetime_seconds = route_entry->lifetime_seconds;
    if (entry->lifetime_seconds != UINT32_MAX)
    {
        sys_timeout(entry->lifetime_seconds * 1000, route_timeout_handler, entry);
    }

    return entry;
}

static inline bool is_better_route(const esp_route_entry_t * lhs, const esp_route_entry_t * rhs)
{
    if (rhs == NULL)
    {
        return true;
    }
    if (lhs == NULL)
    {
        return false;
    }
    return (lhs->prefix_length > rhs->prefix_length) ||
        (lhs->prefix_length == rhs->prefix_length && lhs->preference > rhs->preference);
}

static inline bool route_match(const esp_route_entry_t * route, const ip6_addr_t * dest)
{
    return memcmp(dest, route->prefix.addr, route->prefix_length / 8) == 0;
}

struct netif * lwip_hook_ip6_route(const ip6_addr_t * src, const ip6_addr_t * dest)
{
    esp_route_entry_t * route = NULL;

    for (esp_route_entry_t * iter = s_route_entries; iter != NULL; iter = iter->next)
    {
        if (route_match(iter, dest) && is_better_route(iter, route))
        {
            route = iter;
        }
    }

    if (route)
    {
        return route->netif;
    }
    else
    {
        return NULL;
    }
}

const ip6_addr_t * lwip_hook_nd6_get_gw(struct netif * netif, const ip6_addr_t * dest)
{
    esp_route_entry_t * route = NULL;

    for (esp_route_entry_t * iter = s_route_entries; iter != NULL; iter = iter->next)
    {
        if (iter->netif == netif && route_match(iter, dest) && is_better_route(iter, route))
        {
            route = iter;
        }
    }

    if (route)
    {
        return &route->gateway;
    }
    else
    {
        return NULL;
    }
}
