/*
 * This file was generated by mib2c and is intended for use as
 * a mib module for the ucd-snmp snmpd agent.
 *
 * Portions of this file are copyrighted by:
 * Copyright (c) 2016 VMware, Inc. All rights reserved.
 * Use is subject to license terms specified in the COPYING file
 * distributed with the Net-SNMP package.
 */


/*
 * This should always be included first before anything else
 */
#include <net-snmp/net-snmp-config.h>

#include <sys/types.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif


/*
 * minimal include directives
 */
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include "header_complex.h"
#include "snmpNotifyTable_data.h"
#include "snmpNotifyFilterProfileTable_data.h"


/*
 * global storage of our data, saved in and configured by header_complex()
 */
static struct header_complex_index *snmpNotifyFilterProfileTableStorage =
    NULL;
static int _active = 0;

void parse_snmpNotifyFilterProfileTable(const char *token, char *line);
int store_snmpNotifyFilterProfileTable(int majorID, int minorID,
                                       void *serverarg, void *clientarg);

/*
 * init_snmpNotifyFilterProfileTable():
 *   Initialization routine.  This is called when the agent starts up.
 *   At a minimum, registration of your variables should take place here.
 */
void
init_snmpNotifyFilterProfileTable_data(void)
{
    int done = 0;

    if (++done != 1)
        return;

    DEBUGMSGTL(("snmpNotifyFilterProfileTable", "initializing...  "));

    /*
     * register our config handler(s) to deal with registrations
     */
    snmpd_register_config_handler("snmpNotifyFilterProfileTable",
                                  parse_snmpNotifyFilterProfileTable, NULL,
                                  NULL);

    /*
     * we need to be called back later to store our data
     */
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                           store_snmpNotifyFilterProfileTable, NULL);
}

void
shutdown_snmpNotifyFilterProfileTable_data(void)
{
    struct header_complex_index *hptr, *nhptr;

    DEBUGMSGTL(("snmpNotifyFilterProfileTable", "shutdown...  "));

    for (hptr = snmpNotifyFilterProfileTableStorage; hptr; hptr = nhptr) {
        struct snmpNotifyFilterProfileTable_data *nptr = hptr->data;
        nhptr = hptr->next;
        if (nptr->snmpNotifyFilterProfileStorType == ST_READONLY) {
            header_complex_extract_entry(&snmpNotifyFilterProfileTableStorage,
                                         hptr);
            snmpNotifyFilterProfileTable_free(nptr);
        }
    }
    snmpNotifyFilterProfileTableStorage = NULL;

    DEBUGMSGTL(("trap:notifyFilterProfile:shutdown",
                "active count %d\n", _active));
    if (_active != 0) {
        DEBUGMSGTL(("trap:notifyFilterProfile:shutdown",
                    "unexpected count %d after cleanup!\n", _active));
        snmp_log(LOG_WARNING,
                 "notifyFilterProfile count %d, not 0, after shutdown.\n",
                 _active);
    }

}

void
snmpNotifyFilterProfileTable_free(struct snmpNotifyFilterProfileTable_data
                                  *data)
{
    if (NULL == data)
        return;

    SNMP_FREE(data->snmpTargetParamsName);
    SNMP_FREE(data->snmpNotifyFilterProfileName);
    free(data);
    --_active;
}

/*
 *
 */
struct snmpNotifyFilterProfileTable_data *
snmpNotifyFilterProfileTable_create(const char *paramsName,
                                    size_t paramsName_len,
                                    const char *profileName,
                                    size_t profileName_len)
{
    struct snmpNotifyFilterProfileTable_data *profile = NULL;

    if ((paramsName_len > NOTIFY_NAME_MAX) || (0 == paramsName_len) || 
        (profileName_len > NOTIFY_NAME_MAX)|| (0 == profileName_len)) {
        DEBUGMSGTL(("snmpNotifyFilterProfileTable",
                    "bad params or profile name\n"));
        return NULL;
    }

    profile = SNMP_MALLOC_STRUCT(snmpNotifyFilterProfileTable_data);
    if (NULL == profile) {
        snmp_log(LOG_ERR,
                 "could not allocate snmpNotifyFilterProfileTable_data\n");
        return NULL;
    }
    ++_active;

    profile->snmpTargetParamsName = malloc(paramsName_len+1);
    profile->snmpNotifyFilterProfileName = malloc(profileName_len+1);
    if (NULL == profile->snmpTargetParamsName ||
        NULL == profile->snmpNotifyFilterProfileName) {
        snmp_log(LOG_ERR,
                 "could not allocate snmpNotifyFilterProfileTable_data data\n");
        snmpNotifyFilterProfileTable_free(profile);
        return NULL;
    }

    memcpy(profile->snmpTargetParamsName, paramsName, paramsName_len);
    profile->snmpTargetParamsNameLen = paramsName_len;
    profile->snmpTargetParamsName[paramsName_len] = 0;

    memcpy(profile->snmpNotifyFilterProfileName, profileName, profileName_len);
    profile->snmpNotifyFilterProfileNameLen = profileName_len;
    profile->snmpNotifyFilterProfileName[profileName_len] = 0;

    profile->snmpNotifyFilterProfileRowStatus = RS_NOTREADY;
    profile->snmpNotifyFilterProfileStorType = ST_READONLY;

    return profile;
}

/*
 * snmpNotifyFilterProfileTable_add(): adds a structure node to our data set
 */
int
snmpNotifyFilterProfileTable_add(struct snmpNotifyFilterProfileTable_data
                                 *thedata)
{
    netsnmp_variable_list *vars = NULL;
    int retVal;

    DEBUGMSGTL(("snmpNotifyFilterProfileTable", "adding data...  "));
    /*
     * add the index variables to the varbind list, which is
     * used by header_complex to index the data
     */

    snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR,
                              (u_char *) thedata->snmpTargetParamsName,
                              thedata->snmpTargetParamsNameLen);

    if (header_complex_maybe_add_data(&snmpNotifyFilterProfileTableStorage, vars,
                                      thedata, 1) != NULL){
       DEBUGMSGTL(("snmpNotifyFilterProfileTable", "registered an entry\n"));
       retVal = SNMPERR_SUCCESS;
    }else{
       retVal = SNMPERR_GENERR;
    }


    DEBUGMSGTL(("snmpNotifyFilterProfileTable", "done.\n"));
    return retVal;
}

struct snmpNotifyFilterProfileTable_data *
snmpNotifyFilterProfileTable_extract(struct snmpNotifyFilterProfileTable_data *
                                    thedata)
{
    struct header_complex_index *hptr;

    for (hptr = snmpNotifyFilterProfileTableStorage; hptr; hptr = hptr->next) {
        if (hptr->data == thedata)
            break;
    }
    if (NULL != hptr) {
        struct snmpNotifyFilterProfileTable_data *nptr = hptr->data;
        header_complex_extract_entry(&snmpNotifyFilterProfileTableStorage,
                                     hptr);
        return nptr;
    }
    return NULL;
}


int
snmpNotifyFilterProfileTable_remove(struct snmpNotifyFilterProfileTable_data *
                                    thedata)
{
    struct snmpNotifyFilterProfileTable_data * found =
        snmpNotifyFilterProfileTable_extract(thedata);
    if (NULL != found) {
        snmpNotifyFilterProfileTable_free(found);
        return 1;
    }
    return 0;
}


struct snmpNotifyFilterProfileTable_data *
snmpNotifyFilterProfileTable_find(const char *name, size_t len)
{
    netsnmp_variable_list *vars = NULL;
    struct snmpNotifyFilterProfileTable_data *data;

    /*
     * put requested info into var structure
     */
    snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR,
                              (const u_char *) name, len);

    /*
     * get the data from the header_complex storage
     */
    data = (struct snmpNotifyFilterProfileTable_data *)
        header_complex_get(snmpNotifyFilterProfileTableStorage, vars);

    /*
     * free search index
     */
    snmp_free_var(vars);

    return data;
}

struct snmpNotifyFilterProfileTable_data *
snmpNotifyFilterProfileTable_oldapi_find(struct variable *vp,
                                         oid *name, size_t *nameLen, int exact,
                                         size_t *var_len,
                                         WriteMethod ** write_method)
{
    return header_complex((struct header_complex_index *)
                          snmpNotifyFilterProfileTableStorage, vp, name,
                          nameLen, exact, var_len, write_method);
}


char *
get_FilterProfileName(const char *paramName, size_t paramName_len,
                      size_t * profileName_len)
{
    struct snmpNotifyFilterProfileTable_data *data =
        snmpNotifyFilterProfileTable_find(paramName, paramName_len);

    /*
     * return the requested information (if this row is active)
     */
    if (data && data->snmpNotifyFilterProfileRowStatus == RS_ACTIVE) {
        *profileName_len = data->snmpNotifyFilterProfileNameLen;
        return data->snmpNotifyFilterProfileName;
    }

    *profileName_len = 0;
    return NULL;
}

/*
 * parse_snmpNotifyFilterProfileTable():
 *   parses .conf file entries needed to configure the mib.
 */
void
parse_snmpNotifyFilterProfileTable(const char *token, char *line)
{
    size_t          tmpint;
    struct snmpNotifyFilterProfileTable_data *StorageTmp =
        SNMP_MALLOC_STRUCT(snmpNotifyFilterProfileTable_data);

    DEBUGMSGTL(("snmpNotifyFilterProfileTable", "parsing config...  "));

    if (StorageTmp == NULL) {
        config_perror("malloc failure");
        return;
    }

    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &StorageTmp->snmpTargetParamsName,
                              &StorageTmp->snmpTargetParamsNameLen);
    if (StorageTmp->snmpTargetParamsName == NULL) {
        config_perror("invalid specification for snmpTargetParamsName");
        free(StorageTmp);
        return;
    }

    line =
        read_config_read_data(ASN_OCTET_STR, line,
                              &StorageTmp->snmpNotifyFilterProfileName,
                              &StorageTmp->snmpNotifyFilterProfileNameLen);
    if (StorageTmp->snmpNotifyFilterProfileName == NULL) {
        config_perror("invalid specification for snmpNotifyFilterProfileName");
        snmpNotifyFilterProfileTable_free(StorageTmp);
        return;
    }

    line =
        read_config_read_data(ASN_INTEGER, line,
                              &StorageTmp->snmpNotifyFilterProfileStorType,
                              &tmpint);

    line =
        read_config_read_data(ASN_INTEGER, line,
                              &StorageTmp->
                              snmpNotifyFilterProfileRowStatus, &tmpint);

    if (snmpNotifyFilterProfileTable_add(StorageTmp) != SNMPERR_SUCCESS){
        snmpNotifyFilterProfileTable_free(StorageTmp);
        StorageTmp = NULL;
    }

    DEBUGMSGTL(("snmpNotifyFilterProfileTable", "done.\n"));
}




/*
 * store_snmpNotifyFilterProfileTable():
 *   stores .conf file entries needed to configure the mib.
 */
int
store_snmpNotifyFilterProfileTable(int majorID, int minorID,
                                   void *serverarg, void *clientarg)
{
    char            line[SNMP_MAXBUF];
    char           *cptr;
    struct snmpNotifyFilterProfileTable_data *StorageTmp;
    struct header_complex_index *hcindex;


    DEBUGMSGTL(("snmpNotifyFilterProfileTable", "storing data...  "));

    for (hcindex = snmpNotifyFilterProfileTableStorage; hcindex != NULL;
         hcindex = hcindex->next) {
        StorageTmp =
            (struct snmpNotifyFilterProfileTable_data *) hcindex->data;

        if ((StorageTmp->snmpNotifyFilterProfileStorType == ST_NONVOLATILE) ||
            (StorageTmp->snmpNotifyFilterProfileStorType == ST_PERMANENT)) {

            memset(line, 0, sizeof(line));
            strcat(line, "snmpNotifyFilterProfileTable ");
            cptr = line + strlen(line);

            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->snmpTargetParamsName,
                                       &StorageTmp->
                                       snmpTargetParamsNameLen);
            cptr =
                read_config_store_data(ASN_OCTET_STR, cptr,
                                       &StorageTmp->
                                       snmpNotifyFilterProfileName,
                                       &StorageTmp->
                                       snmpNotifyFilterProfileNameLen);
            cptr =
                read_config_store_data(ASN_INTEGER, cptr,
                                       &StorageTmp->
                                       snmpNotifyFilterProfileStorType,
                                       NULL);
            cptr =
                read_config_store_data(ASN_INTEGER, cptr,
                                       &StorageTmp->
                                       snmpNotifyFilterProfileRowStatus,
                                       NULL);

            snmpd_store_config(line);
        }
    }
    DEBUGMSGTL(("snmpNotifyFilterProfileTable", "done.\n"));
    return 0;
}
