/*
 * DisMan Expression MIB:
 *    Implementation of the object table configuration handling.
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "utilities/iquery.h"
#include "disman/expr/expObject.h"
#include "disman/expr/expObjectConf.h"

/* Initializes the expObjectConf module */
void
init_expObjectConf(void)
{
    init_expObject_table_data();

    /*
     * Register config handler for persistent storage
     *     of dynamically configured entries.
     */
    snmpd_register_config_handler("_expOTable", parse_expOTable, NULL, NULL);

    /*
     * Register to save (non-fixed) entries when the agent shuts down
     */
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                           store_expOTable, NULL);
}



/* ================================================
 *
 *  Handlers for loading/storing persistent expression entries
 *
 * ================================================ */

char *
_parse_expOCols( char *line, struct expObject *entry )
{
    void  *vp;
    size_t tmp;

    vp   = entry->expObjectID;
    entry->expObjectID_len = MAX_OID_LEN;
    line = read_config_read_data(ASN_OBJECT_ID, line, &vp,
                                &entry->expObjectID_len);

    line = read_config_read_data(ASN_UNSIGNED,  line, &tmp, NULL);
    entry->expObjectSampleType = tmp;

    vp   = entry->expObjDeltaD;
    entry->expObjDeltaD_len = MAX_OID_LEN;
    line = read_config_read_data(ASN_OBJECT_ID, line, &vp,
                                &entry->expObjDeltaD_len);

    line = read_config_read_data(ASN_UNSIGNED,  line, &tmp, NULL);
    entry->expObjDiscontinuityType = tmp;

    vp   = entry->expObjCond;
    entry->expObjCond_len = MAX_OID_LEN;
    line = read_config_read_data(ASN_OBJECT_ID, line, &vp,
                                &entry->expObjCond_len);

    line = read_config_read_data(ASN_UNSIGNED, line,  &tmp, NULL);
    entry->flags |= tmp;

    return line;
}


void
parse_expOTable(const char *token, char *line)
{
    char   owner[EXP_STR1_LEN+1];
    char   oname[EXP_STR1_LEN+1];
    long   idx;
    void  *vp;
    size_t len;
    struct expObject *entry;

    DEBUGMSGTL(("disman:expr:conf", "Parsing mteObjectTable config...  "));

    /*
     * Read in the index information for this entry
     *  and create a (non-fixed) data structure for it.
     */
    memset( owner, 0, sizeof(owner));
    memset( oname, 0, sizeof(oname));
    len   = EXP_STR1_LEN; vp = owner;
    line  = read_config_read_data(ASN_OCTET_STR, line, &vp,  &len);
    len   = EXP_STR1_LEN; vp = oname;
    line  = read_config_read_data(ASN_OCTET_STR, line, &vp,  &len);
    line  = read_config_read_data(ASN_UNSIGNED,  line, &idx, NULL);
    entry = expObject_createEntry( owner, oname, idx, 0 );

    DEBUGMSG(("disman:expr:conf", "(%s, %s, %ld) ", owner, oname, idx));
    
    /*
     * Read in the accessible column values.
     */
    line = _parse_expOCols( line, entry );
    /*
     * XXX - Will need to read in the 'iquery' access information
     */
    entry->flags |= EXP_OBJ_FLAG_VALID;

    DEBUGMSG(("disman:expr:conf", "\n"));
}


int
store_expOTable(int majorID, int minorID, void *serverarg, void *clientarg)
{
    char                  line[SNMP_MAXBUF];
    char                 *cptr;
    void                 *vp;
    size_t                tint;
    netsnmp_tdata_row    *row;
    struct expObject *entry;


    DEBUGMSGTL(("disman:expr:conf", "Storing expObjectTable config:\n"));

    for (row = netsnmp_tdata_row_first( expObject_table_data );
         row;
         row = netsnmp_tdata_row_next( expObject_table_data, row )) {

        /*
         * Skip entries that were set up via static config directives
         */
        entry = (struct expObject *)netsnmp_tdata_row_entry( row );
        if ( entry->flags & EXP_OBJ_FLAG_FIXED )
            continue;

        DEBUGMSGTL(("disman:expr:conf", "  Storing (%s %s %lu)\n",
                    entry->expOwner, entry->expName, entry->expObjectIndex));

        /*
         * Save the basic expObject entry, indexes...
         */
        memset(line, 0, sizeof(line));
        strcat(line, "_expOTable ");
        cptr = line + strlen(line);

        vp   = entry->expOwner;          tint = strlen( vp );
        cptr = read_config_store_data(   ASN_OCTET_STR, cptr, &vp,  &tint );
        vp   = entry->expName;           tint = strlen( vp );
        cptr = read_config_store_data(   ASN_OCTET_STR, cptr, &vp,  &tint );
        tint = entry->expObjectIndex;
        cptr = read_config_store_data(   ASN_UNSIGNED,  cptr, &tint, NULL );

        /*
         * ... and column values.
         */
        vp   = entry->expObjectID;
        tint = entry->expObjectID_len;
        cptr = read_config_store_data(   ASN_OBJECT_ID, cptr, &vp,  &tint );
        tint = entry->expObjectSampleType;
        cptr = read_config_store_data(   ASN_UNSIGNED,  cptr, &tint, NULL );

        vp   = entry->expObjDeltaD;
        tint = entry->expObjDeltaD_len;
        cptr = read_config_store_data(   ASN_OBJECT_ID, cptr, &vp,  &tint );
        tint = entry->expObjDiscontinuityType;
        cptr = read_config_store_data(   ASN_UNSIGNED,  cptr, &tint, NULL );

        vp   = entry->expObjCond;
        tint = entry->expObjCond_len;
        cptr = read_config_store_data(   ASN_OBJECT_ID, cptr, &vp,  &tint );

        tint = entry->flags;
        cptr = read_config_store_data(   ASN_UNSIGNED,  cptr, &tint, NULL );

        snmpd_store_config(line);
    }

    DEBUGMSGTL(("disman:expr:conf", "  done.\n"));
    return SNMPERR_SUCCESS;
}
