#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include "sctpTables_common.h"
#include "sctpAssocTable.h"
#include "sctpAssocRemAddrTable.h"
#include "sctpAssocLocalAddrTable.h"
#include "sctpLookupLocalPortTable.h"
#include "sctpLookupRemPortTable.h"
#include "sctpLookupRemHostNameTable.h"
#include "sctpLookupRemPrimIPAddrTable.h"
#include "sctpLookupRemIPAddrTable.h"

static void
sctpAssocTable_collect_invalid(void *what, void *magic)
{
    sctpAssocTable_entry *entry = what;
    netsnmp_container *to_delete = magic;

    if (entry->valid)
        entry->valid = 0;
    else
        CONTAINER_INSERT(to_delete, entry);
}

/*
 * Remove all entries from sctpAssocTable, which are not marked as valid.
 * All valid entries are then marked as invalid (to delete them in next cache
 * load, if the entry is not updated). 
 */
void
sctpAssocTable_delete_invalid(netsnmp_container *assocTable)
{
    netsnmp_container *to_delete = netsnmp_container_find("lifo");

    CONTAINER_FOR_EACH(assocTable, sctpAssocTable_collect_invalid,
                       to_delete);

    while (CONTAINER_SIZE(to_delete)) {
        sctpAssocTable_entry *entry = CONTAINER_FIRST(to_delete);
        CONTAINER_REMOVE(assocTable, entry);
        sctpAssocTable_entry_free(entry);
        CONTAINER_REMOVE(to_delete, NULL);
    }
    CONTAINER_FREE(to_delete);
}

static void
sctpAssocRemAddrTable_collect_invalid(void *what, void *magic)
{
    sctpAssocRemAddrTable_entry *entry = what;
    netsnmp_container *to_delete = magic;

    if (entry->valid)
        entry->valid = 0;
    else
        CONTAINER_INSERT(to_delete, entry);
}

/*
 * Remove all entries from sctpAssocRemAddrTable, which are not marked as valid.
 * All valid entries are then marked as invalid (to delete them in next cache
 * load, if the entry is not updated). 
 */
void
sctpAssocRemAddrTable_delete_invalid(netsnmp_container *remAddrTable)
{
    netsnmp_container *to_delete = netsnmp_container_find("lifo");

    CONTAINER_FOR_EACH(remAddrTable, sctpAssocRemAddrTable_collect_invalid,
                       to_delete);

    while (CONTAINER_SIZE(to_delete)) {
        sctpAssocRemAddrTable_entry *entry = CONTAINER_FIRST(to_delete);
        CONTAINER_REMOVE(remAddrTable, entry);
        sctpAssocRemAddrTable_entry_free(entry);
        CONTAINER_REMOVE(to_delete, NULL);
    }
    CONTAINER_FREE(to_delete);
}

static void
sctpAssocLocalAddrTable_collect_invalid(void *what, void *magic)
{
    sctpAssocLocalAddrTable_entry *entry = what;
    netsnmp_container *to_delete = magic;

    if (entry->valid)
        entry->valid = 0;
    else
        CONTAINER_INSERT(to_delete, entry);
}

/*
 * Remove all entries from sctpAssocLocalAddrTable, which are not marked as valid.
 * All valid entries are then marked as invalid (to delete them in next cache
 * load, if the entry is not updated). 
 */
void
sctpAssocLocalAddrTable_delete_invalid(netsnmp_container *localAddrTable)
{
    netsnmp_container *to_delete = netsnmp_container_find("lifo");

    CONTAINER_FOR_EACH(localAddrTable,
                       sctpAssocLocalAddrTable_collect_invalid, to_delete);

    while (CONTAINER_SIZE(to_delete)) {
        sctpAssocLocalAddrTable_entry *entry = CONTAINER_FIRST(to_delete);
        CONTAINER_REMOVE(localAddrTable, entry);
        sctpAssocLocalAddrTable_entry_free(entry);
        CONTAINER_REMOVE(to_delete, NULL);
    }
    CONTAINER_FREE(to_delete);
}


int
sctpAssocRemAddrTable_add_or_update(netsnmp_container *remAddrTable,
                                    sctpAssocRemAddrTable_entry * entry)
{
    /*
     * we have full sctpAssocLocalAddrTable entry, update or add it in the container 
     */
    sctpAssocRemAddrTable_entry *old;

    entry->valid = 1;

    /*
     * try to find it in the container 
     */
    sctpAssocRemAddrTable_entry_update_index(entry);
    old = CONTAINER_FIND(remAddrTable, entry);

    if (old != NULL) {
        /*
         * update existing entry, don't overwrite the timestamp 
         */
        time_t          timestamp = old->sctpAssocRemAddrStartTime;
        if (timestamp == 0 && entry->sctpAssocRemAddrStartTime == 0)
            timestamp = netsnmp_get_agent_uptime();     /* set the timestamp if it was not set before */
        sctpAssocRemAddrTable_entry_copy(entry, old);
        old->sctpAssocRemAddrStartTime = timestamp;
        sctpAssocRemAddrTable_entry_free(entry);

    } else {
        /*
         * the entry is new, add it there 
         */
        if (entry->sctpAssocRemAddrStartTime == 0) {
            entry->sctpAssocRemAddrStartTime = netsnmp_get_agent_uptime();
        }
        CONTAINER_INSERT(remAddrTable, entry);
    }

    return SNMP_ERR_NOERROR;
}

int
sctpAssocLocalAddrTable_add_or_update(netsnmp_container *localAddrTable,
                                      sctpAssocLocalAddrTable_entry *
                                      entry)
{
    /*
     * we have full sctpAssocLocalAddrTable entry, update or add it in the container 
     */
    sctpAssocLocalAddrTable_entry *old;

    entry->valid = 1;

    /*
     * try to find it in the container 
     */
    sctpAssocLocalAddrTable_entry_update_index(entry);
    old = CONTAINER_FIND(localAddrTable, entry);

    if (old != NULL) {
        /*
         * update existing entry, don't overwrite the timestamp
         */
        time_t          timestamp = old->sctpAssocLocalAddrStartTime;
        if (timestamp == 0 && entry->sctpAssocLocalAddrStartTime == 0)
            timestamp = netsnmp_get_agent_uptime();     /* set the timestamp if it was not set before */
        sctpAssocLocalAddrTable_entry_copy(entry, old);
        old->sctpAssocLocalAddrStartTime = timestamp;
        sctpAssocLocalAddrTable_entry_free(entry);

    } else {
        /*
         * the entry is new, add it there 
         */
        if (entry->sctpAssocLocalAddrStartTime == 0) {
            entry->sctpAssocLocalAddrStartTime =
                netsnmp_get_agent_uptime();
        }
        CONTAINER_INSERT(localAddrTable, entry);
    }

    return SNMP_ERR_NOERROR;
}

int
sctpAssocTable_add_or_update(netsnmp_container *assocTable,
                             sctpAssocTable_entry * entry)
{
    /*
     * we have full sctpAssocTable entry, update or add it in the container 
     */
    sctpAssocTable_entry *old;

    entry->valid = 1;

    /*
     * try to find it in the container 
     */
    sctpAssocTable_entry_update_index(entry);
    old = CONTAINER_FIND(assocTable, entry);

    if (old != NULL) {
        /*
         * update existing entry, don't overwrite the timestamp
         */
        time_t          timestamp = old->sctpAssocStartTime;
        if (timestamp == 0 && entry->sctpAssocStartTime == 0
            && entry->sctpAssocState >= SCTPASSOCSTATE_ESTABLISHED)
            timestamp = netsnmp_get_agent_uptime();     /* set the timestamp if it was not set before and entry reaches the right state */
        sctpAssocTable_entry_copy(entry, old);
        old->sctpAssocStartTime = timestamp;
        sctpAssocTable_entry_free(entry);

    } else {
        /*
         * the entry is new, add it there 
         */
        if (entry->sctpAssocStartTime == 0
            && entry->sctpAssocState >= SCTPASSOCSTATE_ESTABLISHED) {
            entry->sctpAssocStartTime = netsnmp_get_agent_uptime();
        }
        CONTAINER_INSERT(assocTable, entry);
    }

    return SNMP_ERR_NOERROR;
}

static void
sctpTables_add_local_port(sctpAssocTable_entry * assoc,
                          sctpTables_containers * containers)
{
    sctpLookupLocalPortTable_entry *entry;

    entry = sctpLookupLocalPortTable_entry_create();
    if (entry == NULL) {
        DEBUGMSGTL(("sctp:tables:fill_lookup",
                    "cannot create sctpLookupLocalPortTable_entry"));
        return;
    }

    entry->sctpAssocId = assoc->sctpAssocId;
    entry->sctpAssocLocalPort = assoc->sctpAssocLocalPort;
    entry->sctpLookupLocalPortStartTime = assoc->sctpAssocStartTime;
    sctpLookupLocalPortTable_entry_update_index(entry);
    CONTAINER_INSERT(containers->sctpLookupLocalPortTable, entry);
}

static void
sctpTables_add_rem_port(sctpAssocTable_entry * assoc,
                        sctpTables_containers * containers)
{
    sctpLookupRemPortTable_entry *entry;

    entry = sctpLookupRemPortTable_entry_create();
    if (entry == NULL) {
        DEBUGMSGTL(("sctp:tables:fill_lookup",
                    "cannot create sctpLookupRemPortTable_entry"));
        return;
    }

    entry->sctpAssocId = assoc->sctpAssocId;
    entry->sctpAssocRemPort = assoc->sctpAssocRemPort;
    entry->sctpLookupRemPortStartTime = assoc->sctpAssocStartTime;
    sctpLookupRemPortTable_entry_update_index(entry);
    CONTAINER_INSERT(containers->sctpLookupRemPortTable, entry);
}

static void
sctpTables_add_rem_hostname(sctpAssocTable_entry * assoc,
                            sctpTables_containers * containers)
{
    sctpLookupRemHostNameTable_entry *entry;

    if (assoc->sctpAssocRemHostName_len == 0)
        return;                 /* the association does not know its hostname */

    entry = sctpLookupRemHostNameTable_entry_create();
    if (entry == NULL) {
        DEBUGMSGTL(("sctp:tables:fill_lookup",
                    "cannot create sctpLookupRemHostNameTable_entry"));
        return;
    }

    entry->sctpAssocId = assoc->sctpAssocId;
    entry->sctpAssocRemHostName_len = assoc->sctpAssocRemHostName_len;
    memcpy(entry->sctpAssocRemHostName, assoc->sctpAssocRemHostName,
           assoc->sctpAssocRemHostName_len);
    entry->sctpLookupRemHostNameStartTime = assoc->sctpAssocStartTime;

    sctpLookupRemHostNameTable_entry_update_index(entry);
    CONTAINER_INSERT(containers->sctpLookupRemHostNameTable, entry);
}

static void
sctpTables_add_rem_prim_ip_addr(sctpAssocTable_entry * assoc,
                                sctpTables_containers * containers)
{
    sctpLookupRemPrimIPAddrTable_entry *entry;

    entry = sctpLookupRemPrimIPAddrTable_entry_create();
    if (entry == NULL) {
        DEBUGMSGTL(("sctp:tables:fill_lookup",
                    "cannot create sctpLookupRemPrimIPAddrTable_entry"));
        return;
    }

    entry->sctpAssocId = assoc->sctpAssocId;
    entry->sctpAssocRemPrimAddrType = assoc->sctpAssocRemPrimAddrType;
    entry->sctpAssocRemPrimAddr_len = assoc->sctpAssocRemPrimAddr_len;
    memcpy(entry->sctpAssocRemPrimAddr, assoc->sctpAssocRemPrimAddr,
           assoc->sctpAssocRemPrimAddr_len);
    entry->sctpLookupRemPrimIPAddrStartTime = assoc->sctpAssocStartTime;

    sctpLookupRemPrimIPAddrTable_entry_update_index(entry);
    CONTAINER_INSERT(containers->sctpLookupRemPrimIPAddrTable, entry);
}

static void
sctpTables_fill_lookup_assoc(void *what, void *magic)
{
    sctpAssocTable_entry *entry = what;
    sctpTables_containers *containers = magic;

    sctpTables_add_local_port(entry, containers);
    sctpTables_add_rem_port(entry, containers);
    sctpTables_add_rem_hostname(entry, containers);
    sctpTables_add_rem_prim_ip_addr(entry, containers);
}

static void
sctpTables_add_rem_ip_addr(sctpAssocRemAddrTable_entry * rem_addr,
                           sctpTables_containers * containers)
{
    sctpLookupRemIPAddrTable_entry *entry;

    entry = sctpLookupRemIPAddrTable_entry_create();
    if (entry == NULL) {
        DEBUGMSGTL(("sctp:tables:fill_lookup",
                    "cannot create sctpLookupRemIPAddrTable_entry"));
        return;
    }

    entry->sctpAssocId = rem_addr->sctpAssocId;
    entry->sctpAssocRemAddrType = rem_addr->sctpAssocRemAddrType;
    entry->sctpAssocRemAddr_len = rem_addr->sctpAssocRemAddr_len;
    memcpy(entry->sctpAssocRemAddr, rem_addr->sctpAssocRemAddr,
           rem_addr->sctpAssocRemAddr_len);
    entry->sctpLookupRemIPAddrStartTime =
        rem_addr->sctpAssocRemAddrStartTime;

    sctpLookupRemIPAddrTable_entry_update_index(entry);
    CONTAINER_INSERT(containers->sctpLookupRemIPAddrTable, entry);
}

static void
sctpTables_fill_lookup_rem_addr(void *what, void *magic)
{
    sctpAssocRemAddrTable_entry *entry = what;
    sctpTables_containers *containers = magic;
    sctpTables_add_rem_ip_addr(entry, containers);
}

int
sctpTables_fill_lookup(sctpTables_containers * containers)
{
    /*
     * clear all the lookup tables 
     */
    sctpLookupLocalPortTable_container_clear(containers->
                                             sctpLookupLocalPortTable);
    sctpLookupRemPortTable_container_clear(containers->
                                           sctpLookupRemPortTable);
    sctpLookupRemHostNameTable_container_clear(containers->
                                               sctpLookupRemHostNameTable);
    sctpLookupRemPrimIPAddrTable_container_clear(containers->
                                                 sctpLookupRemPrimIPAddrTable);
    sctpLookupRemIPAddrTable_container_clear(containers->
                                             sctpLookupRemIPAddrTable);

    /*
     * fill the lookup tables 
     */
    CONTAINER_FOR_EACH(containers->sctpAssocTable,
                       sctpTables_fill_lookup_assoc, containers);
    CONTAINER_FOR_EACH(containers->sctpAssocRemAddrTable,
                       sctpTables_fill_lookup_rem_addr, containers);

    return SNMP_ERR_NOERROR;
}



int
sctpTables_load(void)
{
    sctpTables_containers containers;
    int             ret;
    u_long          flags = 0;

    containers.sctpAssocTable = sctpAssocTable_get_container();
    containers.sctpAssocRemAddrTable =
        sctpAssocRemAddrTable_get_container();
    containers.sctpAssocLocalAddrTable =
        sctpAssocLocalAddrTable_get_container();
    containers.sctpLookupLocalPortTable =
        sctpLookupLocalPortTable_get_container();
    containers.sctpLookupRemPortTable =
        sctpLookupRemPortTable_get_container();
    containers.sctpLookupRemHostNameTable =
        sctpLookupRemHostNameTable_get_container();
    containers.sctpLookupRemPrimIPAddrTable =
        sctpLookupRemPrimIPAddrTable_get_container();
    containers.sctpLookupRemIPAddrTable =
        sctpLookupRemIPAddrTable_get_container();

    ret = sctpTables_arch_load(&containers, &flags);

    if (flags & SCTP_TABLES_LOAD_FLAG_DELETE_INVALID) {
        sctpAssocTable_delete_invalid(containers.sctpAssocTable);
        sctpAssocRemAddrTable_delete_invalid(containers.
                                             sctpAssocRemAddrTable);
        sctpAssocLocalAddrTable_delete_invalid(containers.
                                               sctpAssocLocalAddrTable);
    }

    if (flags & SCTP_TABLES_LOAD_FLAG_AUTO_LOOKUP) {
        ret = sctpTables_fill_lookup(&containers);
    }

    return ret;
}
