/*
 *  Swrun MIB architecture support
 *
 * $Id: swrun.c 15768 2007-01-22 16:18:29Z rstory $
 */
/*
 * 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/swrun.h>


/**---------------------------------------------------------------------*/
/*
 * local static vars
 */
static int _swrun_init = 0;
       int _swrun_max  = 0;
static netsnmp_cache     *swrun_cache     = NULL;
static netsnmp_container *swrun_container = NULL;

netsnmp_container * netsnmp_swrun_container(void);
netsnmp_cache     * netsnmp_swrun_cache    (void);

/*
 * local static prototypes
 */
static void _swrun_entry_release(netsnmp_swrun_entry * entry,
                                            void *unused);

/**---------------------------------------------------------------------*/
/*
 * external per-architecture functions prototypes
 *
 * These shouldn't be called by the general public, so they aren't in
 * the header file.
 */
extern void netsnmp_arch_swrun_init(void);
extern int netsnmp_arch_swrun_container_load(netsnmp_container* container,
                                             u_int load_flags);

/**
 * initialization
 */
void
init_swrun(void)
{
    DEBUGMSGTL(("swrun:access", "init\n"));

    if (1 == _swrun_init)
        return;

    _swrun_init = 1;

    (void)netsnmp_swrun_container();
    netsnmp_arch_swrun_init();
    (void) netsnmp_swrun_cache();
}

void
shutdown_swrun(void)
{
    DEBUGMSGTL(("swrun:access", "shutdown\n"));

}

int
swrun_count_processes( void )
{
    netsnmp_cache_check_and_reload(swrun_cache);
    return ( swrun_container ? CONTAINER_SIZE(swrun_container) : 0 );
}

int
swrun_max_processes( void )
{
    return _swrun_max;
}

int
swrun_count_processes_by_name( char *name )
{
    netsnmp_swrun_entry *entry;
    netsnmp_iterator  *it;
    int i = 0;

    netsnmp_cache_check_and_reload(swrun_cache);
    if ( !swrun_container || !name )
        return 0;    /* or -1 */

    it = CONTAINER_ITERATOR( swrun_container );
    while ( entry = ITERATOR_NEXT( it )) {
        if (0 == strcmp( entry->hrSWRunName, name ))
            i++;
    }
    ITERATOR_RELEASE( it );

    return i;
}


/**---------------------------------------------------------------------*/
/*
 * cache functions
 */

static int
_cache_load( netsnmp_cache *cache,  void *magic )
{
    netsnmp_swrun_container_load( swrun_container, 0 );
    return 0;
}

static void
_cache_free( netsnmp_cache *cache,  void *magic )
{
    netsnmp_swrun_container_free_items( swrun_container );
    return;
}

/**
 * create swrun cache
 */
netsnmp_cache *
netsnmp_swrun_cache(void)
{
    oid    hrSWRunTable_oid[]   = { 1, 3, 6, 1, 2, 1, 25, 4, 2 };
    size_t hrSWRunTable_oid_len = OID_LENGTH(hrSWRunTable_oid);

    if ( !swrun_cache ) {
        swrun_cache = netsnmp_cache_create(30,   /* timeout in seconds */
                           _cache_load,  _cache_free,
                           hrSWRunTable_oid, hrSWRunTable_oid_len);
        if (swrun_cache)
            swrun_cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;
    }
    return swrun_cache;
}


/**---------------------------------------------------------------------*/
/*
 * container functions
 */
/**
 * create swrun container
 */
netsnmp_container *
netsnmp_swrun_container(void)
{
    netsnmp_container *container;

    DEBUGMSGTL(("swrun:container", "init\n"));

    /*
     * create the container.
     */
  if (!swrun_container) {
    swrun_container = netsnmp_container_find("swrun:table_container");
    if (NULL == swrun_container)
        return NULL;

    swrun_container->container_name = strdup("swrun container");
  }

    return swrun_container;
}

/**
 * load swrun information in specified container
 *
 * @param container empty container to be filled.
 *                  pass NULL to have the function create one.
 * @param load_flags flags to modify behaviour. Examples:
 *                   NETSNMP_SWRUN_ALL_OR_NONE
 *
 * @retval NULL  error
 * @retval !NULL pointer to container
 */
netsnmp_container*
netsnmp_swrun_container_load(netsnmp_container* user_container, u_int load_flags)
{
    netsnmp_container* container = user_container;
    int rc;

    DEBUGMSGTL(("swrun:container:load", "load\n"));
    netsnmp_assert(1 == _swrun_init);

    if (NULL == container)
        container = netsnmp_swrun_container();
    if (NULL == container) {
        snmp_log(LOG_ERR, "no container specified/found for swrun\n");
        return NULL;
    }

    rc =  netsnmp_arch_swrun_container_load(container, load_flags);
    if (0 != rc) {
        if (NULL == user_container) {
            netsnmp_swrun_container_free(container, NETSNMP_SWRUN_NOFLAGS);
            container = NULL;
        }
        else if (load_flags & NETSNMP_SWRUN_ALL_OR_NONE) {
            DEBUGMSGTL(("swrun:container:load",
                        " discarding partial results\n"));
            netsnmp_swrun_container_free_items(container);
        }
    }

    return container;
}

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

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

    if(! (free_flags & NETSNMP_SWRUN_DONT_FREE_ITEMS))
        netsnmp_swrun_container_free_items(container);

    CONTAINER_FREE(container);
}

void
netsnmp_swrun_container_free_items(netsnmp_container *container)
{
    DEBUGMSGTL(("swrun:container", "free_items\n"));

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

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

/**---------------------------------------------------------------------*/
/*
 * swrun_entry functions
 */
/**
 */
netsnmp_swrun_entry *
netsnmp_swrun_entry_get_by_index(netsnmp_container *container, oid index)
{
    netsnmp_index   tmp;

    DEBUGMSGTL(("swrun:entry", "by_index\n"));
    netsnmp_assert(1 == _swrun_init);

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

    tmp.len = 1;
    tmp.oids = &index;

    return (netsnmp_swrun_entry *) CONTAINER_FIND(container, &tmp);
}

/**
 */
netsnmp_swrun_entry *
netsnmp_swrun_entry_create(int32_t index)
{
    netsnmp_swrun_entry *entry =
        SNMP_MALLOC_TYPEDEF(netsnmp_swrun_entry);

    if(NULL == entry)
        return NULL;

    entry->hrSWRunIndex = index;
    entry->hrSWRunType = 1; /* unknown */
    entry->hrSWRunStatus = 2; /* runnable */

    entry->oid_index.len = 1;
    entry->oid_index.oids = (oid *) & entry->hrSWRunIndex;

    return entry;
}

/**
 */
NETSNMP_INLINE void
netsnmp_swrun_entry_free(netsnmp_swrun_entry * entry)
{
    if (NULL == entry)
        return;

    /*
     * SNMP_FREE not needed, for any of these, 
     * since the whole entry is about to be freed
     */
    free(entry);
}

/**---------------------------------------------------------------------*/
/*
 * Utility routines
 */

/**
 */
static void
_swrun_entry_release(netsnmp_swrun_entry * entry, void *context)
{
    netsnmp_swrun_entry_free(entry);
}


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

    netsnmp_container_init_list();

    /** swrun,verbose:swrun,9:swrun,8:swrun,5:swrun */
    if (tokens)
        debug_register_tokens(tokens);
    else
        debug_register_tokens("swrun");
    snmp_set_do_debugging(1);

    init_swrun();
    netsnmp_swrun_container_load(NULL, 0);
    shutdown_swrun();

    return 0;
}
#endif
