/*
 * netsnmp_data_list.c
 *
 * $Id$
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>

/*
 * prototypes
 */
NETSNMP_INLINE void
netsnmp_data_list_add_node(netsnmp_data_list **head, netsnmp_data_list *node);


/** @defgroup data_list generic linked-list data handling with a string as a key.
 * @ingroup library
 * @{
*/

/** frees the data and a name at a given data_list node.
 * Note that this doesn't free the node itself.
 * @param node the node for which the data should be freed
 */
NETSNMP_INLINE void
netsnmp_free_list_data(netsnmp_data_list *node)
{
    Netsnmp_Free_List_Data *beer;
    if (!node)
        return;

    beer = node->free_func;
    if (beer)
        (beer) (node->data);
    SNMP_FREE(node->name);
}

/** frees all data and nodes in a list.
 * @param head the top node of the list to be freed.
 */
NETSNMP_INLINE void
netsnmp_free_all_list_data(netsnmp_data_list *head)
{
    netsnmp_data_list *tmpptr;
    for (; head;) {
        netsnmp_free_list_data(head);
        tmpptr = head;
        head = head->next;
        SNMP_FREE(tmpptr);
    }
}

/** adds creates a data_list node given a name, data and a free function ptr.
 * @param name the name of the node to cache the data.
 * @param data the data to be stored under that name
 * @param beer A function that can free the data pointer (in the future)
 * @return a newly created data_list node which can be given to the netsnmp_add_list_data function.
 */
NETSNMP_INLINE netsnmp_data_list *
netsnmp_create_data_list(const char *name, void *data,
                         Netsnmp_Free_List_Data * beer)
{
    netsnmp_data_list *node;
    
    if (!name)
        return NULL;
    node = SNMP_MALLOC_TYPEDEF(netsnmp_data_list);
    if (!node)
        return NULL;
    node->name = strdup(name);
    if (!node->name) {
      free(node);
      return NULL;
    }
    node->data = data;
    node->free_func = beer;
    return node;
}

/** adds data to a datalist
 * @note netsnmp_data_list_add_node is preferred
 * @param head a pointer to the head node of a data_list
 * @param node a node to stash in the data_list
 */
/**  */
NETSNMP_INLINE void
netsnmp_add_list_data(netsnmp_data_list **head, netsnmp_data_list *node)
{
    netsnmp_data_list_add_node(head, node);
}

/** adds data to a datalist
 * @param head a pointer to the head node of a data_list
 * @param node a node to stash in the data_list
 */
NETSNMP_INLINE void
netsnmp_data_list_add_node(netsnmp_data_list **head, netsnmp_data_list *node)
{
    netsnmp_data_list *ptr;

    netsnmp_assert(NULL != head);
    netsnmp_assert(NULL != node);
    netsnmp_assert(NULL != node->name);

    if (!*head) {
        *head = node;
        return;
    }

    DEBUGMSGTL(("data_list","adding key '%s'\n", node->name));
    if (0 == strcmp(node->name, (*head)->name)) {
        netsnmp_assert(!"list key == is unique"); /* always fail */
        snmp_log(LOG_WARNING,
                 "WARNING: adding duplicate key '%s' to data list\n",
                 node->name);
    }

    for (ptr = *head; ptr->next != NULL; ptr = ptr->next) {
        netsnmp_assert(NULL != ptr->name);
        if (0 == strcmp(node->name, ptr->name)) {
            netsnmp_assert(!"list key == is unique"); /* always fail */
            snmp_log(LOG_WARNING,
                     "WARNING: adding duplicate key '%s' to data list\n",
                     node->name);
        }
    }

    netsnmp_assert(NULL != ptr);
    if (ptr)                    /* should always be true */
        ptr->next = node;
}

/** adds data to a datalist
 * @param head a pointer to the head node of a data_list
 * @param name the name of the node to cache the data.
 * @param data the data to be stored under that name
 * @param beer A function that can free the data pointer (in the future)
 * @return a newly created data_list node which was inserted in the list
 */
NETSNMP_INLINE netsnmp_data_list *
netsnmp_data_list_add_data(netsnmp_data_list **head, const char *name,
                           void *data, Netsnmp_Free_List_Data * beer)
{
    netsnmp_data_list *node;
    if (!name) {
        snmp_log(LOG_ERR,"no name provided.");
        return NULL;
    }
    node = netsnmp_create_data_list(name, data, beer);
    if(NULL == node) {
        snmp_log(LOG_ERR,"could not allocate memory for node.");
        return NULL;
    }
    
    netsnmp_add_list_data(head, node);

    return node;
}

/** returns a data_list node's data for a given name within a data_list
 * @param head the head node of a data_list
 * @param name the name to find
 * @return a pointer to the data cached at that node
 */
NETSNMP_INLINE void    *
netsnmp_get_list_data(netsnmp_data_list *head, const char *name)
{
    if (!name)
        return NULL;
    for (; head; head = head->next)
        if (head->name && strcmp(head->name, name) == 0)
            break;
    if (head)
        return head->data;
    return NULL;
}

/** returns a data_list node for a given name within a data_list
 * @param head the head node of a data_list
 * @param name the name to find
 * @return a pointer to the data_list node
 */
NETSNMP_INLINE netsnmp_data_list    *
netsnmp_get_list_node(netsnmp_data_list *head, const char *name)
{
    if (!name)
        return NULL;
    for (; head; head = head->next)
        if (head->name && strcmp(head->name, name) == 0)
            break;
    if (head)
        return head;
    return NULL;
}

/** Removes a named node from a data_list (and frees it)
 * @param realhead a pointer to the head node of a data_list
 * @param name the name to find and remove
 * @return 0 on successful find-and-delete, 1 otherwise.
 */
int
netsnmp_remove_list_node(netsnmp_data_list **realhead, const char *name)
{
    netsnmp_data_list *head, *prev;
    if (!name)
        return 1;
    for (head = *realhead, prev = NULL; head;
         prev = head, head = head->next) {
        if (head->name && strcmp(head->name, name) == 0) {
            if (prev)
                prev->next = head->next;
            else
                *realhead = head->next;
            netsnmp_free_list_data(head);
            free(head);
            return 0;
        }
    }
    return 1;
}

/** used to store registered save/parse handlers (specifically, parsing info) */
static netsnmp_data_list *saveHead;

/** registers to store a data_list set of data at persistent storage time
 *
 * @param datalist the data to be saved
 * @param type the name of the application to save the data as.  If left NULL the default application name that was registered during the init_snmp call will be used (recommended).
 * @param token the unique token identifier string to use as the first word in the persistent file line.
 * @param data_list_save_ptr a function pointer which will be called to save the rest of the data to a buffer.
 * @param data_list_read_ptr a function pointer which can read the remainder of a saved line and return the application specific void * pointer.
 * @param data_list_free_ptr a function pointer which will be passed to the data node for freeing it in the future when/if the list/node is cleaned up or destroyed.
 */
void
netsnmp_register_save_list(netsnmp_data_list **datalist,
                           const char *type, const char *token,
                           Netsnmp_Save_List_Data *data_list_save_ptr,
                           Netsnmp_Read_List_Data *data_list_read_ptr,
                           Netsnmp_Free_List_Data *data_list_free_ptr)
{
    netsnmp_data_list_saveinfo *info;

    if (!data_list_save_ptr && !data_list_read_ptr)
        return;

    info = SNMP_MALLOC_TYPEDEF(netsnmp_data_list_saveinfo);

    if (!info) {
        snmp_log(LOG_ERR, "couldn't malloc a netsnmp_data_list_saveinfo typedef");
        return;
    }

    info->datalist = datalist;
    info->token = token;
    info->type = type;
    if (!info->type) {
        info->type = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                           NETSNMP_DS_LIB_APPTYPE);
    }

    /* function which will save the data */
    info->data_list_save_ptr = data_list_save_ptr;
    if (data_list_save_ptr)
        snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                               netsnmp_save_all_data_callback, info);

    /* function which will read the data back in */
    info->data_list_read_ptr = data_list_read_ptr;
    if (data_list_read_ptr) {
        /** @todo netsnmp_register_save_list should handle the same token name being saved from different types? */
        netsnmp_add_list_data(&saveHead,
                              netsnmp_create_data_list(token, info, NULL));
        register_config_handler(type, token, netsnmp_read_data_callback,
                                NULL /* XXX */, NULL);
    }

    info->data_list_free_ptr = data_list_free_ptr;
}


/** intended to be registerd as a callback operation.
 * It should be registered using:
 *
 * snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, netsnmp_save_all_data_callback, INFO_POINTER);
 *
 * where INFO_POINTER is a pointer to a netsnmp_data_list_saveinfo object containing apporpriate registration information
 */
int
netsnmp_save_all_data_callback(int major, int minor,
                               void *serverarg, void *clientarg) {
    netsnmp_data_list_saveinfo *info = (netsnmp_data_list_saveinfo *)clientarg;

    if (!clientarg) {
        snmp_log(LOG_WARNING, "netsnmp_save_all_data_callback called with no passed data");
        return SNMP_ERR_NOERROR;
    }

    netsnmp_save_all_data(*(info->datalist), info->type, info->token,
                          info->data_list_save_ptr);
    return SNMP_ERR_NOERROR;
}    

/** intended to be called as a callback during persistent save operations.
 * See the netsnmp_save_all_data_callback for where this is typically used. */
int
netsnmp_save_all_data(netsnmp_data_list *head,
                      const char *type, const char *token,
                      Netsnmp_Save_List_Data * data_list_save_ptr)
{
    char buf[SNMP_MAXBUF], *cp;

    for (; head; head = head->next) {
        if (head->name) {
            /* save begining of line */
            snprintf(buf, sizeof(buf), "%s ", token);
            cp = buf + strlen(buf);
            cp = read_config_save_octet_string(cp, (u_char*)head->name,
                                               strlen(head->name));
            *cp++ = ' ';

            /* call registered function to save the rest */
            if (!(data_list_save_ptr)(cp,
                                      sizeof(buf) - strlen(buf),
                                      head->data)) {
                read_config_store(type, buf);
            }
        }
    }
    return SNMP_ERR_NOERROR;
}

/** intended to be registerd as a .conf parser
 * It should be registered using:
 *
 * register_app_config_handler("token", netsnmp_read_data_callback, XXX)
 *
 * where INFO_POINTER is a pointer to a netsnmp_data_list_saveinfo object
 * containing apporpriate registration information
 * @todo make netsnmp_read_data_callback deal with a free routine
 */
void
netsnmp_read_data_callback(const char *token, char *line) {
    netsnmp_data_list_saveinfo *info;
    char *dataname = NULL;
    size_t dataname_len;
    void *data = NULL;

    /* find the stashed information about what we're parsing */
    info = (netsnmp_data_list_saveinfo *) netsnmp_get_list_data(saveHead, token);
    if (!info) {
        snmp_log(LOG_WARNING, "netsnmp_read_data_callback called without previously registered subparser");
        return;
    }

    /* read in the token */
    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &dataname, &dataname_len);

    if (!line || !dataname)
        return;

    /* call the sub-parser to read the rest */
    data = (info->data_list_read_ptr)(line, strlen(line));

    if (!data) {
        free(dataname);
        return;
    }

    /* add to the datalist */
    netsnmp_add_list_data(info->datalist,
                          netsnmp_create_data_list(dataname, data,
                                                   info->data_list_free_ptr));

    return;
}
/**  @} */

