/*
 * swinst.c : hrSWInstalledTable data access
 */
/*
 * Copyright (C) 2007 Apple, Inc. All rights reserved.
 * Use is subject to license terms specified in the COPYING file
 * distributed with the Net-SNMP package.
 */
#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/data_access/swinst.h>

#include <stdlib.h>
#include <unistd.h>

/* ---------------------------------------------------------------------
 */

static void netsnmp_swinst_entry_free_cb(netsnmp_swinst_entry *, void *);

extern void netsnmp_swinst_arch_init(void);
extern void netsnmp_swinst_arch_shutdown(void);
extern int netsnmp_swinst_arch_load(netsnmp_container *, u_int);

void init_swinst( void )
{
    static int initialized = 0;

    DEBUGMSGTL(("swinst", "init called\n"));

    if (initialized)
        return; /* already initialized */


    /*
     * call arch init code
     */
    netsnmp_swinst_arch_init();
}

void shutdown_swinst( void )
{
    DEBUGMSGTL(("swinst", "shutdown called\n"));

    netsnmp_swinst_arch_shutdown();
}

/* ---------------------------------------------------------------------
 */

/*
 * load a container with installed software. If user_container is NULL,
 * a new container will be allocated and returned, and the caller
 * is responsible for releasing the allocated memory when done.
 *
 * if flags contains NETSNMP_SWINST_ALL_OR_NONE and any error occurs,
 * the container will be completely cleared.
 */
netsnmp_container *
netsnmp_swinst_container_load( netsnmp_container *user_container, int flags )
{
    netsnmp_container *container = user_container;
    int arch_rc;

    DEBUGMSGTL(("swinst:container", "load\n"));

    /*
     * create the container, if needed
     */
    if (NULL == container) {
        container = netsnmp_container_find("swinst:table_container");
        if (NULL == container)
            return NULL;
    }
    if (NULL == container->container_name)
        container->container_name = strdup("swinst container");

    /*
     * call the arch specific code to load the container
     */
    arch_rc = netsnmp_swinst_arch_load( container, flags );
    if (arch_rc && (flags & NETSNMP_SWINST_ALL_OR_NONE)) {
        /*
         * caller does not want a partial load, so empty the container.
         * if we created the container, destroy it.
         */
        netsnmp_swinst_container_free_items(container);
        if (container != user_container) {
            netsnmp_swinst_container_free(container, flags);
        }
    }
    
    return container;
}

void
netsnmp_swinst_container_free(netsnmp_container *container, u_int free_flags)
{
    DEBUGMSGTL(("swinst:container", "free\n"));

    if (NULL == container) {
        snmp_log(LOG_ERR,
                 "invalid container for netsnmp_swinst_container_free\n");
        return;
    }

    if(! (free_flags & NETSNMP_SWINST_DONT_FREE_ITEMS))
        netsnmp_swinst_container_free_items(container);

    CONTAINER_FREE(container);
}

/*
 * free a swinst container
 */
void netsnmp_swinst_container_free_items(netsnmp_container *container)
{
    DEBUGMSGTL(("swinst:container", "free_items\n"));

    if (NULL == container) {
        snmp_log(LOG_ERR,
                 "invalid container for netsnmp_swinst_container_free_items\n");
        return;
    }

    /*
     * free all items.
     */
    CONTAINER_CLEAR(container,
                    (netsnmp_container_obj_func*)netsnmp_swinst_entry_free_cb,
                    NULL);
}


/* ---------------------------------------------------------------------
 */

/*
 * create a new row in the table 
 */
netsnmp_swinst_entry *
netsnmp_swinst_entry_create(int32_t swIndex)
{
    netsnmp_swinst_entry *entry;

    entry = SNMP_MALLOC_TYPEDEF(netsnmp_swinst_entry);
    if (!entry)
        return NULL;

    entry->swIndex = swIndex;
    entry->oid_index.len = 1;
    entry->oid_index.oids = &entry->swIndex;

    entry->swType = HRSWINSTALLEDTYPE_APPLICATION;

    return entry;
}

/*
 * free a row
 */
void
netsnmp_swinst_entry_free(netsnmp_swinst_entry *entry)
{
    DEBUGMSGTL(("swinst:entry:free", "index %lu\n", entry->swIndex));

    free(entry);
}

/*
 * free a row
 */
static void
netsnmp_swinst_entry_free_cb(netsnmp_swinst_entry *entry, void *context)
{
    free(entry);
}

/*
 * remove a row from the table 
 */
void
netsnmp_swinst_entry_remove(netsnmp_container * container,
                            netsnmp_swinst_entry *entry)
{
    DEBUGMSGTL(("swinst:container", "remove\n"));
    if (!entry)
        return;                 /* Nothing to remove */
    CONTAINER_REMOVE(container, entry);
}

/* ---------------------------------------------------------------------
 */

#ifdef TEST
int main(int argc, char *argv[])
{
    const char *tokens = getenv("SNMP_DEBUG");

    netsnmp_container_init_list();

    /** swinst,verbose:swinst */
    if (tokens)
        debug_register_tokens(tokens);
    else
        debug_register_tokens("swinst");
    snmp_set_do_debugging(1);

    init_swinst();
    netsnmp_swinst_container_load(NULL, 0);
    shutdown_swinst();

    return 0;
}
#endif
