#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;

    if (name)
        table->name = strdup(name);
    table->container = netsnmp_container_find( "table_container" );
    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
     */
    CONTAINER_INSERT( table->container, row );
    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;

    switch ( reqinfo->mode ) {
    case MODE_GET:
    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)
                continue;           /* ack */
            row = netsnmp_container_table_row_extract( request );

            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));
        }
    }

    /* 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_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);
}


/* ==================================
 *
 * 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 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 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 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);
}

/** @} 
 */
