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

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

#include <net-snmp/agent/table_tdata.h>

#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#include <net-snmp/agent/table.h>
#include <net-snmp/agent/table_container.h>
#include <net-snmp/agent/read_only.h>

#if HAVE_DMALLOC_H
#include <dmalloc.h>
#endif

/** @defgroup tdata tdata
 *  Implement a table with datamatted storage.
 *  @ingroup table
 *
 *  This helper helps you implement a table where all the rows are
 *  expected to be stored within the agent itself and not in some
 *  external storage location.  It can be used to store a list of
 *  rows, where a row consists of the indexes to the table and a
 *  generic data pointer.  You can then implement a subhandler which
 *  is passed the exact row definition and data it must return data
 *  for or accept data for.  Complex GETNEXT handling is greatly
 *  simplified in this case.
 *
 *  @{
 */

/* ==================================
 *
 * TData API: Table maintenance
 *
 * ================================== */

/*
 * generates the index portion of an table oid from a varlist.
 */
void
_netsnmp_tdata_generate_index_oid(netsnmp_tdata_row *row)
{
    build_oid(&row->oid_index.oids, &row->oid_index.len, NULL, 0, row->indexes);
}

/** creates and returns a 'tdata' table data structure */
netsnmp_tdata *
netsnmp_tdata_create_table(const char *name, long flags)
{
    netsnmp_tdata *table = SNMP_MALLOC_TYPEDEF(netsnmp_tdata);
    if ( !table )
        return NULL;

    table->flags = flags;
    if (name)
        table->name = strdup(name);

    if (!(table->flags & TDATA_FLAG_NO_CONTAINER)) {
        table->container = netsnmp_container_find( name );
        if (!table->container)
            table->container = netsnmp_container_find( "table_container" );
        if (table->container)
            table->container->container_name = strdup(name);
    }
    return table;
}

/** creates and returns a 'tdata' table data structure */
void
netsnmp_tdata_delete_table(netsnmp_tdata *table)
{
    if (!table)
       return;

    if (table->name)
       free(table->name);
    if (table->container)
       CONTAINER_FREE(table->container);
    
    SNMP_FREE(table);
    return;
}

/** creates and returns a pointer to new row data structure */
netsnmp_tdata_row *
netsnmp_tdata_create_row(void)
{
    netsnmp_tdata_row *row = SNMP_MALLOC_TYPEDEF(netsnmp_tdata_row);
    return row;
}

/** clones a 'tdata' row. DOES NOT CLONE THE TABLE-SPECIFIC ENTRY DATA. */
netsnmp_tdata_row *
netsnmp_tdata_clone_row(netsnmp_tdata_row *row)
{
    netsnmp_tdata_row *newrow = NULL;
    if (!row)
        return NULL;

    newrow = netsnmp_memdup(row, sizeof(netsnmp_tdata_row));
    if (!newrow)
        return NULL;

    if (row->indexes) {
        newrow->indexes = snmp_clone_varbind(newrow->indexes);
        if (!newrow->indexes) {
            SNMP_FREE(newrow);
            return NULL;
        }
    }

    if (row->oid_index.oids) {
        newrow->oid_index.oids =
            snmp_duplicate_objid(row->oid_index.oids, row->oid_index.len);
        if (!newrow->oid_index.oids) {
            if (newrow->indexes)
                snmp_free_varbind(newrow->indexes);
            SNMP_FREE(newrow);
            return NULL;
        }
    }

    return newrow;
}

/** copy the contents of a 'tdata' row.
    DOES NOT COPY THE TABLE-SPECIFIC ENTRY DATA. */
int
netsnmp_tdata_copy_row(netsnmp_tdata_row *dst_row, netsnmp_tdata_row *src_row)
{
     if ( !src_row || !dst_row )
         return -1;

    memcpy((u_char *) dst_row, (u_char *) src_row,
           sizeof(netsnmp_tdata_row));
    if (src_row->indexes) {
        dst_row->indexes = snmp_clone_varbind(src_row->indexes);
        if (!dst_row->indexes)
            return -1;
    }

    if (src_row->oid_index.oids) {
        dst_row->oid_index.oids = snmp_duplicate_objid(src_row->oid_index.oids,
                                                       src_row->oid_index.len);
        if (!dst_row->oid_index.oids)
            return -1;
    }

    return 0;
}

/** deletes the memory used by the specified row
 *  returns the table-specific entry data
 *  (that it doesn't know how to delete) */
void           *
netsnmp_tdata_delete_row(netsnmp_tdata_row *row)
{
    void           *data;

    if (!row)
        return NULL;

    /*
     * free the memory we can 
     */
    if (row->indexes)
        snmp_free_varbind(row->indexes);
    SNMP_FREE(row->oid_index.oids);
    data = row->data;
    free(row);

    /*
     * return the void * pointer 
     */
    return data;
}

/**
 * Adds a row to the given table (stored in proper lexographical order).
 *
 * returns SNMPERR_SUCCESS on successful addition.
 *      or SNMPERR_GENERR  on failure (E.G., indexes already existed)
 */
int
netsnmp_tdata_add_row(netsnmp_tdata     *table,
                      netsnmp_tdata_row *row)
{
    if (!row || !table)
        return SNMPERR_GENERR;

    if (row->indexes)
        _netsnmp_tdata_generate_index_oid(row);

    if (!row->oid_index.oids) {
        snmp_log(LOG_ERR,
                 "illegal data attempted to be added to table %s (no index)\n",
                 table->name);
        return SNMPERR_GENERR;
    }

    /*
     * The individual index values probably won't be needed,
     *    so this memory can be released.
     * Note that this is purely internal to the helper.
     * The calling application can set this flag as
     *    a hint to the helper that these values aren't
     *    required, but it's up to the helper as to
     *    whether it takes any notice or not!
     */
    if (table->flags & TDATA_FLAG_NO_STORE_INDEXES) {
        snmp_free_varbind(row->indexes);
        row->indexes = NULL;
    }

    /*
     * add this row to the stored table
     */
    if (CONTAINER_INSERT( table->container, row ) != 0)
        return SNMPERR_GENERR;

    DEBUGMSGTL(("tdata_add_row", "added row (%p)\n", row));

    return SNMPERR_SUCCESS;
}

/** swaps out origrow with newrow.  This does *not* delete/free anything! */
void
netsnmp_tdata_replace_row(netsnmp_tdata *table,
                               netsnmp_tdata_row *origrow,
                               netsnmp_tdata_row *newrow)
{
    netsnmp_tdata_remove_row(table, origrow);
    netsnmp_tdata_add_row(table, newrow);
}

/**
 * removes a row from the given table and returns it (no free's called)
 *
 * returns the row pointer itself on successful removing.
 *      or NULL on failure (bad arguments)
 */
netsnmp_tdata_row *
netsnmp_tdata_remove_row(netsnmp_tdata *table,
                              netsnmp_tdata_row *row)
{
    if (!row || !table)
        return NULL;

    CONTAINER_REMOVE( table->container, row );
    return row;
}

/**
 * removes and frees a row of the given table and
 *  returns the table-specific entry data
 *
 * returns the void * pointer on successful deletion.
 *      or NULL on failure (bad arguments)
 */
void           *
netsnmp_tdata_remove_and_delete_row(netsnmp_tdata     *table,
                                    netsnmp_tdata_row *row)
{
    if (!row || !table)
        return NULL;

    /*
     * remove it from the list 
     */
    netsnmp_tdata_remove_row(table, row);
    return netsnmp_tdata_delete_row(row);
}


/* ==================================
 *
 * TData API: MIB maintenance
 *
 * ================================== */

Netsnmp_Node_Handler _netsnmp_tdata_helper_handler;

/** Creates a tdata handler and returns it */
netsnmp_mib_handler *
netsnmp_get_tdata_handler(netsnmp_tdata *table)
{
    netsnmp_mib_handler *ret = NULL;

    if (!table) {
        snmp_log(LOG_INFO,
                 "netsnmp_get_tdata_handler(NULL) called\n");
        return NULL;
    }

    ret = netsnmp_create_handler(TABLE_TDATA_NAME,
                               _netsnmp_tdata_helper_handler);
    if (ret) {
        ret->flags |= MIB_HANDLER_AUTO_NEXT;
        ret->myvoid = (void *) table;
    }
    return ret;
}

/*
 * The helper handler that takes care of passing a specific row of
 * data down to the lower handler(s).  The table_container helper
 * has already taken care of identifying the appropriate row of the
 * table (and converting GETNEXT requests into an equivalent GET request)
 * So all we need to do here is make sure that the row is accessible
 * using tdata-style retrieval techniques as well.
 */
int
_netsnmp_tdata_helper_handler(netsnmp_mib_handler *handler,
                                  netsnmp_handler_registration *reginfo,
                                  netsnmp_agent_request_info *reqinfo,
                                  netsnmp_request_info *requests)
{
    netsnmp_tdata *table = (netsnmp_tdata *) handler->myvoid;
    netsnmp_request_info       *request;
    netsnmp_table_request_info *table_info;
    netsnmp_tdata_row          *row;
    int                         need_processing = 1;

    switch ( reqinfo->mode ) {
    case MODE_GET:
        need_processing = 0; /* only need processing if some vars found */
        /** Fall through */

    case MODE_SET_RESERVE1:

        for (request = requests; request; request = request->next) {
            if (request->processed)
                continue;
    
            table_info = netsnmp_extract_table_info(request);
            if (!table_info) {
                netsnmp_assert(table_info); /* yes, this will always hit */
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR);
                continue;           /* eek */
            }
            row = (netsnmp_tdata_row*)netsnmp_container_table_row_extract( request );
            if (!row && (reqinfo->mode == MODE_GET)) {
                netsnmp_assert(row); /* yes, this will always hit */
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_GENERR);
                continue;           /* eek */
            }
            ++need_processing;
            netsnmp_request_add_list_data(request,
                                      netsnmp_create_data_list(
                                          TABLE_TDATA_TABLE, table, NULL));
            netsnmp_request_add_list_data(request,
                                      netsnmp_create_data_list(
                                          TABLE_TDATA_ROW,   row,   NULL));
        }
        /** skip next handler if processing not needed */
        if (!need_processing)
            handler->flags |= MIB_HANDLER_AUTO_NEXT_OVERRIDE_ONCE;
    }

    /* next handler called automatically - 'AUTO_NEXT' */
    return SNMP_ERR_NOERROR;
}


/** registers a tdata-based MIB table */
int
netsnmp_tdata_register(netsnmp_handler_registration    *reginfo,
                       netsnmp_tdata                   *table,
                       netsnmp_table_registration_info *table_info)
{
    netsnmp_inject_handler(reginfo, netsnmp_get_tdata_handler(table));
    return netsnmp_container_table_register(reginfo, table_info,
                  table->container, TABLE_CONTAINER_KEY_NETSNMP_INDEX);
}

int
netsnmp_tdata_unregister(netsnmp_handler_registration    *reginfo)
{
    /* free table; */
    return netsnmp_container_table_unregister(reginfo);
}

/** extracts the tdata table from the request structure */
netsnmp_tdata *
netsnmp_tdata_extract_table(netsnmp_request_info *request)
{
    return (netsnmp_tdata *) netsnmp_request_get_list_data(request,
                                                           TABLE_TDATA_TABLE);
}

/** extracts the tdata container from the request structure */
netsnmp_container *
netsnmp_tdata_extract_container(netsnmp_request_info *request)
{
    netsnmp_tdata *tdata = (netsnmp_tdata*)
        netsnmp_request_get_list_data(request, TABLE_TDATA_TABLE);
    return ( tdata ? tdata->container : NULL );
}

/** extracts the tdata row being accessed from the request structure */
netsnmp_tdata_row *
netsnmp_tdata_extract_row(netsnmp_request_info *request)
{
    return (netsnmp_tdata_row *) netsnmp_container_table_row_extract(request);
}

/** extracts the (table-specific) entry being accessed from the
 *  request structure */
void           *
netsnmp_tdata_extract_entry(netsnmp_request_info *request)
{
    netsnmp_tdata_row *row =
        (netsnmp_tdata_row *) netsnmp_tdata_extract_row(request);
    if (row)
        return row->data;
    else
        return NULL;
}

/** inserts a newly created tdata row into a request */
NETSNMP_INLINE void
netsnmp_insert_tdata_row(netsnmp_request_info *request,
                         netsnmp_tdata_row *row)
{
    netsnmp_container_table_row_insert(request, (netsnmp_index *)row);
}

/** inserts a newly created tdata row into a request */
NETSNMP_INLINE void
netsnmp_remove_tdata_row(netsnmp_request_info *request,
                         netsnmp_tdata_row *row)
{
    netsnmp_container_table_row_remove(request, (netsnmp_index *)row);
}


/* ==================================
 *
 * Generic API: Row operations
 *
 * ================================== */

/** returns the (table-specific) entry data for a given row */
void *
netsnmp_tdata_row_entry( netsnmp_tdata_row *row )
{
    if (row)
        return row->data;
    else
        return NULL;
}

/** returns the first row in the table */
netsnmp_tdata_row *
netsnmp_tdata_row_first(netsnmp_tdata *table)
{
    return (netsnmp_tdata_row *)CONTAINER_FIRST( table->container );
}

/** finds a row in the 'tdata' table given another row */
netsnmp_tdata_row *
netsnmp_tdata_row_get(  netsnmp_tdata     *table,
                        netsnmp_tdata_row *row)
{
    return (netsnmp_tdata_row*)CONTAINER_FIND( table->container, row );
}

/** returns the next row in the table */
netsnmp_tdata_row *
netsnmp_tdata_row_next( netsnmp_tdata      *table,
                        netsnmp_tdata_row  *row)
{
    return (netsnmp_tdata_row *)CONTAINER_NEXT( table->container, row  );
}

/** finds a row in the 'tdata' table given the index values */
netsnmp_tdata_row *
netsnmp_tdata_row_get_byidx(netsnmp_tdata         *table,
                            netsnmp_variable_list *indexes)
{
    oid             searchfor[      MAX_OID_LEN];
    size_t          searchfor_len = MAX_OID_LEN;

    build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
                      indexes);
    return netsnmp_tdata_row_get_byoid(table, searchfor, searchfor_len);
}

/** finds a row in the 'tdata' table given the index OID */
netsnmp_tdata_row *
netsnmp_tdata_row_get_byoid(netsnmp_tdata *table,
                            oid * searchfor, size_t searchfor_len)
{
    netsnmp_index index;
    if (!table)
        return NULL;

    index.oids = searchfor;
    index.len  = searchfor_len;
    return (netsnmp_tdata_row*)CONTAINER_FIND( table->container, &index );
}

/** finds the lexically next row in the 'tdata' table
    given the index values */
netsnmp_tdata_row *
netsnmp_tdata_row_next_byidx(netsnmp_tdata         *table,
                             netsnmp_variable_list *indexes)
{
    oid             searchfor[      MAX_OID_LEN];
    size_t          searchfor_len = MAX_OID_LEN;

    build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
                      indexes);
    return netsnmp_tdata_row_next_byoid(table, searchfor, searchfor_len);
}

/** finds the lexically next row in the 'tdata' table
    given the index OID */
netsnmp_tdata_row *
netsnmp_tdata_row_next_byoid(netsnmp_tdata *table,
                             oid * searchfor, size_t searchfor_len)
{
    netsnmp_index index;
    if (!table)
        return NULL;

    index.oids = searchfor;
    index.len  = searchfor_len;
    return (netsnmp_tdata_row*)CONTAINER_NEXT( table->container, &index );
}

int
netsnmp_tdata_row_count(netsnmp_tdata *table)
{
    if (!table)
        return 0;
    return CONTAINER_SIZE( table->container );
}

/* ==================================
 *
 * Generic API: Index operations on a 'tdata' table
 *
 * ================================== */


/** compare a row with the given index values */
int
netsnmp_tdata_compare_idx(netsnmp_tdata_row     *row,
                          netsnmp_variable_list *indexes)
{
    oid             searchfor[      MAX_OID_LEN];
    size_t          searchfor_len = MAX_OID_LEN;

    build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
                      indexes);
    return netsnmp_tdata_compare_oid(row, searchfor, searchfor_len);
}

/** compare a row with the given index OID */
int
netsnmp_tdata_compare_oid(netsnmp_tdata_row     *row,
                          oid * compareto, size_t compareto_len)
{
    netsnmp_index *index = (netsnmp_index *)row;
    return snmp_oid_compare( index->oids, index->len,
                             compareto,   compareto_len);
}

int
netsnmp_tdata_compare_subtree_idx(netsnmp_tdata_row     *row,
                                  netsnmp_variable_list *indexes)
{
    oid             searchfor[      MAX_OID_LEN];
    size_t          searchfor_len = MAX_OID_LEN;

    build_oid_noalloc(searchfor, MAX_OID_LEN, &searchfor_len, NULL, 0,
                      indexes);
    return netsnmp_tdata_compare_subtree_oid(row, searchfor, searchfor_len);
}

int
netsnmp_tdata_compare_subtree_oid(netsnmp_tdata_row     *row,
                                  oid * compareto, size_t compareto_len)
{
    netsnmp_index *index = (netsnmp_index *)row;
    return snmp_oidtree_compare( index->oids, index->len,
                                 compareto,   compareto_len);
}

/** @} 
 */
