/*
 * DisMan Event MIB:
 *     Core implementation of the object handling behaviour
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "disman/event/mteObjects.h"

netsnmp_tdata *objects_table_data;

    /*
     * Initialize the container for the object table
     * regardless of which initialisation routine is called first.
     */

void
init_objects_table_data(void)
{
    if (!objects_table_data)
        objects_table_data = netsnmp_tdata_create_table("mteObjectsTable", 0);
}



SNMPCallback _init_default_mteObject_lists;

/** Initializes the mteObjects module */
void
init_mteObjects(void)
{
    init_objects_table_data();

    /*
     * Insert fixed object lists for the default trigger
     * notifications, once the MIB files have been read in.
     */
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, 
                           SNMP_CALLBACK_POST_READ_CONFIG,
                           _init_default_mteObject_lists, NULL);
}


void
_init_default_mteObject( const char *oname, const char *object, int index, int wcard)
{
    struct mteObject *entry;

    entry = mteObjects_addOID( "_snmpd", oname, index, object, 0 );
    if (entry) {
        entry->flags |= MTE_OBJECT_FLAG_ACTIVE|
                        MTE_OBJECT_FLAG_FIXED |
                        MTE_OBJECT_FLAG_VALID;
        if (wcard)
            entry->flags |= MTE_OBJECT_FLAG_WILD;
    }
}

int
_init_default_mteObject_lists( int majorID, int minorID,
                               void *serverargs, void *clientarg)
{
    static int _defaults_init = 0;

    if (_defaults_init)
        return 0;
                                                   /* mteHotTrigger     */
    _init_default_mteObject( "_triggerFire", ".1.3.6.1.2.1.88.2.1.1", 1, 0);
                                                   /* mteHotTargetName  */
    _init_default_mteObject( "_triggerFire", ".1.3.6.1.2.1.88.2.1.2", 2, 0);
                                                   /* mteHotContextName */
    _init_default_mteObject( "_triggerFire", ".1.3.6.1.2.1.88.2.1.3", 3, 0);
                                                   /* mteHotOID         */
    _init_default_mteObject( "_triggerFire", ".1.3.6.1.2.1.88.2.1.4", 4, 0);
                                                   /* mteHotValue       */
    _init_default_mteObject( "_triggerFire", ".1.3.6.1.2.1.88.2.1.5", 5, 0);


                                                   /* mteHotTrigger     */
    _init_default_mteObject( "_triggerFail", ".1.3.6.1.2.1.88.2.1.1", 1, 0);
                                                   /* mteHotTargetName  */
    _init_default_mteObject( "_triggerFail", ".1.3.6.1.2.1.88.2.1.2", 2, 0);
                                                   /* mteHotContextName */
    _init_default_mteObject( "_triggerFail", ".1.3.6.1.2.1.88.2.1.3", 3, 0);
                                                   /* mteHotOID         */
    _init_default_mteObject( "_triggerFail", ".1.3.6.1.2.1.88.2.1.4", 4, 0);
                                                   /* mteFailedReason   */
    _init_default_mteObject( "_triggerFail", ".1.3.6.1.2.1.88.2.1.6", 5, 0);

                                                   /* ifIndex       */
    _init_default_mteObject( "_linkUpDown", ".1.3.6.1.2.1.2.2.1.1", 1, 1);
                                                   /* ifAdminStatus */
    _init_default_mteObject( "_linkUpDown", ".1.3.6.1.2.1.2.2.1.7", 2, 1);
                                                   /* ifOperStatus  */
    _init_default_mteObject( "_linkUpDown", ".1.3.6.1.2.1.2.2.1.8", 3, 1);

    _defaults_init = 1;
    return 0;
}

    /* ===================================================
     *
     * APIs for maintaining the contents of the mteObjectsTable container.
     *
     * =================================================== */

/*
 * Create a new row in the object table 
 */
netsnmp_tdata_row      *
mteObjects_createEntry(const char *owner, const char *oname, int index, int flags)
{
    struct mteObject   *entry;
    netsnmp_tdata_row  *row, *row2;
    size_t owner_len = (owner) ? strlen(owner) : 0;
    size_t oname_len = (oname) ? strlen(oname) : 0;

    /*
     * Create the mteObjects entry, and the
     * (table-independent) row wrapper structure...
     */
    entry = SNMP_MALLOC_TYPEDEF(struct mteObject);
    if (!entry)
        return NULL;


    row = netsnmp_tdata_create_row();
    if (!row) {
        SNMP_FREE(entry);
        return NULL;
    }
    row->data = entry;

    /*
     * ... initialize this row with the indexes supplied
     *     and the default values for the row...
     */
    if (owner)
        memcpy(entry->mteOwner, owner, owner_len);
    netsnmp_tdata_row_add_index(row,         ASN_OCTET_STR,
                                entry->mteOwner, owner_len);
    if (oname)
        memcpy(entry->mteOName, oname, oname_len);
    netsnmp_tdata_row_add_index(row,         ASN_OCTET_STR,
                                entry->mteOName, oname_len);
    entry->mteOIndex = index;
    netsnmp_tdata_row_add_index(row, ASN_INTEGER,
                                &entry->mteOIndex, sizeof(long));

    entry->mteObjectID_len = 2;  /* .0.0 */
    if (flags & MTE_OBJECT_FLAG_FIXED)
        entry->flags |= MTE_OBJECT_FLAG_FIXED;

    /*
     * Check whether there's already a row with the same indexes
     *   (XXX - relies on private internal data ???)
     */
    row2 = netsnmp_tdata_row_get_byoid(objects_table_data,
                                       row->oid_index.oids,
                                       row->oid_index.len); 
    if (row2) {
        if (flags & MTE_OBJECT_FLAG_NEXT) {
            /*
             * If appropriate, keep incrementing the final
             * index value until we find a free slot...
             */
            while (row2) {
                row->oid_index.oids[row->oid_index.len]++;
                row2 = netsnmp_tdata_row_get_byoid(objects_table_data,
                                                   row->oid_index.oids,
                                                  row->oid_index.len); 
            }
        } else {
            /*
             * ... otherwise, this is an error.
             *     Tidy up, and return failure.
             */
            netsnmp_tdata_delete_row(row);
            SNMP_FREE(entry);
            return NULL;
        }
    }

    /*
     * ... finally, insert the row into the (common) table container
     */
    netsnmp_tdata_add_row(objects_table_data, row);
    return row;
}


/*
 * Add a row to the object table 
 */
struct mteObject *
mteObjects_addOID(const char *owner, const char *oname, int index,
                  const char *oid_name_buf, int wild )
{
    netsnmp_tdata_row *row;
    struct mteObject  *entry;
    oid    name_buf[ MAX_OID_LEN ];
    size_t name_buf_len;

    name_buf_len = MAX_OID_LEN;
    if (!snmp_parse_oid(oid_name_buf, name_buf, &name_buf_len)) {
        snmp_log(LOG_ERR, "payload OID: %s\n", oid_name_buf);
        config_perror("unknown payload OID");
        return NULL;
    }

    row = mteObjects_createEntry(owner, oname, index,
                           MTE_OBJECT_FLAG_FIXED|MTE_OBJECT_FLAG_NEXT);
    entry = (struct mteObject *)row->data;

    entry->mteObjectID_len = name_buf_len;
    memcpy(entry->mteObjectID, name_buf, name_buf_len*sizeof(oid));
    if (wild)
        entry->flags |= MTE_OBJECT_FLAG_WILD;
    entry->flags     |= MTE_OBJECT_FLAG_VALID|
                        MTE_OBJECT_FLAG_ACTIVE;

    return entry;
}


/*
 * Remove a row from the event table 
 */
void
mteObjects_removeEntry(netsnmp_tdata_row *row)
{
    struct mteObject *entry;

    if (!row)
        return;                 /* Nothing to remove */
    entry = (struct mteObject *)
        netsnmp_tdata_remove_and_delete_row(objects_table_data, row);
    if (entry)
        SNMP_FREE(entry);
}


/*
 * Remove all matching rows from the event table 
 */
void
mteObjects_removeEntries( const char *owner, char *oname )
{
    netsnmp_tdata_row     *row;
    netsnmp_variable_list  owner_var, oname_var;

    memset(&owner_var, 0, sizeof(owner_var));
    memset(&oname_var, 0, sizeof(oname_var));
    snmp_set_var_typed_value( &owner_var, ASN_OCTET_STR,
                               owner,     strlen(owner));
    snmp_set_var_typed_value( &oname_var, ASN_OCTET_STR,
                               oname,     strlen(oname));
    owner_var.next_variable = &oname_var;

    row = netsnmp_tdata_row_next_byidx( objects_table_data, &owner_var );

    while (row && !netsnmp_tdata_compare_subtree_idx( row, &owner_var )) {
        mteObjects_removeEntry(row);
        row = netsnmp_tdata_row_next_byidx( objects_table_data, &owner_var );
    }
    return;
}


    /* ===================================================
     *
     * API for retrieving a list of matching objects
     *
     * =================================================== */

int
mteObjects_vblist( netsnmp_variable_list *vblist,
               char *owner,  char   *oname,
               oid  *suffix, size_t sfx_len )
{
    netsnmp_tdata_row     *row;
    struct mteObject      *entry;
    netsnmp_variable_list  owner_var, oname_var;
    netsnmp_variable_list *var = vblist;
    oid    name[MAX_OID_LEN];
    size_t name_len;

    if (!oname || !*oname) {
        DEBUGMSGTL(("disman:event:objects", "No objects to add (%s)\n",
                                         owner));
        return 1;   /* Empty object name means nothing to add */
    }

    DEBUGMSGTL(("disman:event:objects", "Objects add (%s, %s)\n",
                                         owner, oname ));

    /*
     * Retrieve any matching entries from the mteObjectTable
     *  and add them to the specified varbind list.
     */
    memset(&owner_var, 0, sizeof(owner_var));
    memset(&oname_var, 0, sizeof(oname_var));
    snmp_set_var_typed_value( &owner_var, ASN_OCTET_STR,
                               owner,      strlen(owner));
    snmp_set_var_typed_value( &oname_var, ASN_OCTET_STR,
                               oname,      strlen(oname));
    owner_var.next_variable = &oname_var;

    row = netsnmp_tdata_row_next_byidx( objects_table_data, &owner_var );

    while (row && !netsnmp_tdata_compare_subtree_idx( row, &owner_var )) {
        entry = (struct mteObject *)netsnmp_tdata_row_entry(row);

        memset(name, 0, MAX_OID_LEN);
        memcpy(name, entry->mteObjectID,
                     entry->mteObjectID_len*sizeof(oid));
        name_len = entry->mteObjectID_len;

        /*
         * If the trigger value is wildcarded (sfx_len > 0),
         *    *and* this object entry is wildcarded,
         *    then add the supplied instance suffix.
         * Otherwise use the Object OID as it stands.
         */
        if (sfx_len &&
            entry->flags & MTE_OBJECT_FLAG_WILD) {
            memcpy(&name[name_len], suffix, sfx_len*sizeof(oid));
            name_len += sfx_len;
        }
        snmp_varlist_add_variable( &var, name, name_len, ASN_NULL, NULL, 0);

        row = netsnmp_tdata_row_next( objects_table_data, row );
    }
    return 0;
}


int
mteObjects_internal_vblist( netsnmp_variable_list *vblist,
                            char   *oname,
                            struct mteTrigger *trigger,
                            netsnmp_session   *sess)
{
    netsnmp_variable_list *var = NULL, *vp;
    oid mteHotTrigger[] = {1, 3, 6, 1, 2, 1, 88, 2, 1, 1, 0};
    oid mteHotTarget[]  = {1, 3, 6, 1, 2, 1, 88, 2, 1, 2, 0};
    oid mteHotContext[] = {1, 3, 6, 1, 2, 1, 88, 2, 1, 3, 0};
    oid mteHotOID[]     = {1, 3, 6, 1, 2, 1, 88, 2, 1, 4, 0};
    oid mteHotValue[]   = {1, 3, 6, 1, 2, 1, 88, 2, 1, 5, 0};

    oid ifIndexOid[]    = {1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 0};
    oid ifAdminStatus[] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 7, 0};
    oid ifOperStatus[]  = {1, 3, 6, 1, 2, 1, 2, 2, 1, 8, 0};

    oid if_index;

    /*
     * Construct the varbinds for this (internal) event...
     */
    if (!strcmp(oname, "_triggerFire")) {

        snmp_varlist_add_variable( &var,
               mteHotTrigger, OID_LENGTH(mteHotTrigger),
               ASN_OCTET_STR, trigger->mteTName,
                       strlen(trigger->mteTName));
        snmp_varlist_add_variable( &var,
               mteHotTarget,  OID_LENGTH(mteHotTarget),
               ASN_OCTET_STR, trigger->mteTriggerTarget,
                       strlen(trigger->mteTriggerTarget));
        snmp_varlist_add_variable( &var,
               mteHotContext, OID_LENGTH(mteHotContext),
               ASN_OCTET_STR, trigger->mteTriggerContext,
                       strlen(trigger->mteTriggerContext));
        snmp_varlist_add_variable( &var,
               mteHotOID,     OID_LENGTH(mteHotOID),
               ASN_OBJECT_ID, (char *)trigger->mteTriggerFired->name,
                              trigger->mteTriggerFired->name_length*sizeof(oid));
        snmp_varlist_add_variable( &var,
               mteHotValue,   OID_LENGTH(mteHotValue),
                              trigger->mteTriggerFired->type,
                              trigger->mteTriggerFired->val.string,
                              trigger->mteTriggerFired->val_len);
    } else if ((!strcmp(oname, "_linkUpDown"  ))) {
        /*
         * The ifOperStatus varbind that triggered this entry
         *  is held in the trigger->mteTriggerFired field
         *
         * We can retrieve the ifIndex and ifOperStatus values
         *  from this varbind.  But first we need to tweak the
         *  static ifXXX OID arrays to include the correct index.
         *  (or this could be passed in from the calling routine?)
         *
         * Unfortunately we don't have the current AdminStatus value,
         *  so we'll need to make another query to retrieve that.
         */
        if_index = trigger->mteTriggerFired->name[10];
        ifIndexOid[    10 ] = if_index;
        ifAdminStatus[ 10 ] = if_index;
        ifOperStatus[  10 ] = if_index;
        snmp_varlist_add_variable( &var,
               ifIndexOid, OID_LENGTH(ifIndexOid),
               ASN_INTEGER, &if_index, sizeof(if_index));

               /* Set up a dummy varbind for ifAdminStatus... */
        snmp_varlist_add_variable( &var,
               ifAdminStatus, OID_LENGTH(ifAdminStatus),
               ASN_INTEGER,
               trigger->mteTriggerFired->val.integer,
               trigger->mteTriggerFired->val_len);
               /* ... then retrieve the actual value */
        netsnmp_query_get( var->next_variable, sess );

        snmp_varlist_add_variable( &var,
               ifOperStatus, OID_LENGTH(ifOperStatus),
               ASN_INTEGER,
               trigger->mteTriggerFired->val.integer,
               trigger->mteTriggerFired->val_len);
    } else {
        DEBUGMSGTL(("disman:event:objects",
                    "Unknown internal objects tag (%s)\n", oname));
        return 1;
    }

    /*
     * ... and insert them into the main varbind list
     *     (at the point specified)
     */
    for (vp = var; vp && vp->next_variable; vp=vp->next_variable)
        ;
    vp->next_variable     = vblist->next_variable;
    vblist->next_variable = var;
    return 0;
}
