#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>

#include <stdio.h>
#include <ctype.h>
#if HAVE_STDLIB_H
#   include <stdlib.h>
#endif
#if HAVE_UNISTD_H
#   include <unistd.h>
#endif
#if HAVE_STRING_H
#   include <string.h>
#else
#  include <strings.h>
#endif

#include <sys/types.h>

#if HAVE_LIMITS_H
#   include <limits.h>
#endif
#if HAVE_SYS_PARAM_H
#   include <sys/param.h>
#endif
#ifdef HAVE_SYS_STAT_H
#   include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#   include <fcntl.h>
#endif

#include <errno.h>

#if HAVE_DMALLOC_H
#  include <dmalloc.h>
#endif

#include <net-snmp/types.h>
#include <net-snmp/library/snmp_debug.h>
#include <net-snmp/library/container.h>
#include <net-snmp/library/file_utils.h>
#include <net-snmp/library/text_utils.h>


/*------------------------------------------------------------------
 *
 * Prototypes
 *
 */
/*
 * parse methods
 */
void
_pm_save_index_string_string(FILE *f, netsnmp_container *cin,
                             int flags);
void
_pm_save_everything(FILE *f, netsnmp_container *cin, int flags);
void
_pm_user_function(FILE *f, netsnmp_container *cin,
                  netsnmp_line_process_info *lpi, int flags);


/*
 * line processors
 */
int _process_line_tvi(netsnmp_line_info *line_info, void *mem,
                      struct netsnmp_line_process_info_s* lpi);



/*------------------------------------------------------------------
 *
 * Text file processing functions
 *
 */

/**
 * process text file, reading into extras
 */
netsnmp_container *
netsnmp_file_text_parse(netsnmp_file *f, netsnmp_container *cin,
                        int parse_mode, u_int flags, void *context)
{
    netsnmp_container *c = cin;
    FILE              *fin;
    int                rc;

    if (NULL == f)
        return NULL;

    if ((NULL == c) && (!(flags & PM_FLAG_NO_CONTAINER))) {
        c = netsnmp_container_find("text_parse:binary_array");
        if (NULL == c)
            return NULL;
    }

    rc = netsnmp_file_open(f);
    if (rc < 0) { /** error already logged */
        if ((NULL !=c) && (c != cin))
            CONTAINER_FREE(c);
        return NULL;
    }
    
    /*
     * get a stream from the file descriptor. This DOES NOT rewind the
     * file (if fd was previously opened).
     */
    fin = fdopen(f->fd, "r");
    if (NULL == fin) {
        if (NS_FI_AUTOCLOSE(f->ns_flags))
            close(f->fd);
        if ((NULL !=c) && (c != cin))
            CONTAINER_FREE(c);
        return NULL;
    }

    switch (parse_mode) {

        case PM_SAVE_EVERYTHING:
            _pm_save_everything(fin, c, flags);
            break;

        case PM_INDEX_STRING_STRING:
            _pm_save_index_string_string(fin, c, flags);
            break;

        case PM_USER_FUNCTION:
            if (NULL != context)
                _pm_user_function(fin, c, (netsnmp_line_process_info*)context,
                                  flags);
            break;

        default:
            snmp_log(LOG_ERR, "unknown parse mode %d\n", parse_mode);
            break;
    }


    /*
     * close the stream, which will have the side effect of also closing
     * the file descriptor, so we need to reset it.
     */
    fclose(fin);
    f->fd = -1;

    return c;
}

netsnmp_container *
netsnmp_text_token_container_from_file(const char *file, u_int flags,
                                       netsnmp_container *cin, void *context)
{
    netsnmp_line_process_info  lpi;
    netsnmp_container         *c = cin, *c_rc;
    netsnmp_file              *fp;

    if (NULL == file)
        return NULL;

    /*
     * allocate file resources
     */
    fp = netsnmp_file_fill(NULL, file, O_RDONLY, 0, 0);
    if (NULL == fp) /** msg already logged */
        return NULL;

    memset(&lpi, 0x0, sizeof(lpi));
    lpi.mem_size = sizeof(netsnmp_token_value_index);
    lpi.process = _process_line_tvi;
    lpi.user_context = context;

    if (NULL == c) {
        c = netsnmp_container_find("string:binary_array");
        if (NULL == c) {
            snmp_log(LOG_ERR,"malloc failed\n");
            netsnmp_file_release(fp);
            return NULL;
        }
    }

    c_rc = netsnmp_file_text_parse(fp, c, PM_USER_FUNCTION, 0, &lpi);

    /*
     * if we got a bad return and the user didn't pass us a container,
     * we need to release the container we allocated.
     */
    if ((NULL == c_rc) && (NULL == cin)) {
        CONTAINER_FREE(c);
        c = NULL;
    }
    else
        c = c_rc;

    /*
     * release file resources
     */
    netsnmp_file_release(fp);
    
    return c;
}


/*------------------------------------------------------------------
 *
 * Text file process modes helper functions
 *
 */

/**
 * @internal
 * parse mode: save everything
 */
void
_pm_save_everything(FILE *f, netsnmp_container *cin, int flags)
{
    char               line[STRINGMAX], *ptr;
    size_t             len;

    netsnmp_assert(NULL != f);
    netsnmp_assert(NULL != cin);

    while (fgets(line, sizeof(line), f) != NULL) {

        ptr = line;
        len = strlen(line) - 1;
        if (line[len] == '\n')
            line[len] = 0;

        /*
         * save blank line or comment?
         */
        if (flags & PM_FLAG_SKIP_WHITESPACE) {
            if (NULL == (ptr = skip_white(ptr)))
                continue;
        }

        ptr = strdup(line);
        if (NULL == ptr) {
            snmp_log(LOG_ERR,"malloc failed\n");
            break;
        }

        CONTAINER_INSERT(cin,ptr);
    }
}

/**
 * @internal
 * parse mode: 
 */
void
_pm_save_index_string_string(FILE *f, netsnmp_container *cin,
                             int flags)
{
    char                        line[STRINGMAX], *ptr;
    netsnmp_token_value_index  *tvi;
    size_t                      count = 0, len;

    netsnmp_assert(NULL != f);
    netsnmp_assert(NULL != cin);

    while (fgets(line, sizeof(line), f) != NULL) {

        ++count;
        ptr = line;
        len = strlen(line) - 1;
        if (line[len] == '\n')
            line[len] = 0;

        /*
         * save blank line or comment?
         */
        if (flags & PM_FLAG_SKIP_WHITESPACE) {
            if (NULL == (ptr = skip_white(ptr)))
                continue;
        }

        tvi = SNMP_MALLOC_TYPEDEF(netsnmp_token_value_index);
        if (NULL == tvi) {
            snmp_log(LOG_ERR,"malloc failed\n");
            break;
        }
            
        /*
         * copy whole line, then set second pointer to
         * after token. One malloc, 2 strings!
         */
        tvi->index = count;
        tvi->token = strdup(line);
        if (NULL == tvi->token) {
            snmp_log(LOG_ERR,"malloc failed\n");
            free(tvi);
            break;
        }
        tvi->value.cp = skip_not_white(tvi->token);
        if (NULL != tvi->value.cp) {
            *(tvi->value.cp) = 0;
            ++(tvi->value.cp);
        }
        CONTAINER_INSERT(cin, tvi);
    }
}

/**
 * @internal
 * parse mode: 
 */
void
_pm_user_function(FILE *f, netsnmp_container *cin,
                  netsnmp_line_process_info *lpi, int flags)
{
    char                        buf[STRINGMAX];
    netsnmp_line_info           li;
    void                       *mem = NULL;
    int                         rc;

    netsnmp_assert(NULL != f);
    netsnmp_assert(NULL != cin);

    /*
     * static buf, or does the user want the memory?
     */
    if (flags & PMLP_FLAG_ALLOC_LINE) {
        if (0 != lpi->line_max)
            li.line_max =  lpi->line_max;
        else
            li.line_max = STRINGMAX;
        li.line = (char *)calloc(li.line_max, 1);
        if (NULL == li.line) {
            snmp_log(LOG_ERR,"malloc failed\n");
            return;
        }
    }
    else {
        li.line = buf;
        li.line_max = sizeof(buf);
    }
        
    li.index = 0;
    while (fgets(li.line, li.line_max, f) != NULL) {

        ++li.index;
        li.start = li.line;
        li.line_len = strlen(li.line) - 1;
        if ((!(lpi->flags & PMLP_FLAG_LEAVE_NEWLINE)) &&
            (li.line[li.line_len] == '\n'))
            li.line[li.line_len] = 0;
        
        /*
         * save blank line or comment?
         */
        if (!(lpi->flags & PMLP_FLAG_PROCESS_WHITESPACE)) {
            if (NULL == (li.start = skip_white(li.start)))
                continue;
        }

        /*
         *  do we need to allocate memory for the use?
         * if the last call didn't use the memory we allocated,
         * re-use it. Otherwise, allocate new chunk.
         */
        if ((0 != lpi->mem_size) && (NULL == mem)) {
            mem = calloc(lpi->mem_size, 1);
            if (NULL == mem) {
                snmp_log(LOG_ERR,"malloc failed\n");
                break;
            }
        }

        /*
         * do they want a copy ot the line?
         */
        if (lpi->flags & PMLP_FLAG_STRDUP_LINE) {
            li.start = strdup(li.start);
            if (NULL == li.start) {
                snmp_log(LOG_ERR,"malloc failed\n");
                break;
            }
        }
        else if (lpi->flags & PMLP_FLAG_ALLOC_LINE) {
            li.start = li.line;
        }

        /*
         * call the user function. If the function wants to save
         * the memory chunk, insert it in the container, the clear
         * pointer so we reallocate next time.
         */
        li.start_len = strlen(li.start);
        rc = (*lpi->process)(&li, mem, lpi);
        if (PMLP_RC_MEMORY_USED == rc) {

            if (!(lpi->flags & PMLP_FLAG_NO_CONTAINER))
                CONTAINER_INSERT(cin, mem);
            
            mem = NULL;
            
            if (lpi->flags & PMLP_FLAG_ALLOC_LINE) {
	        li.line = (char *)calloc(li.line_max, 1);
                if (NULL == li.line) {
                    snmp_log(LOG_ERR,"malloc failed\n");
                    break;
                }
            }
        }
        else if (PMLP_RC_MEMORY_UNUSED == rc ) {
            /*
             * they didn't use the memory. if li.start was a strdup, we have
             * to release it. leave mem, we can re-use it (its a fixed size).
             */
            if (lpi->flags & PMLP_FLAG_STRDUP_LINE)
                free(li.start); /* no point in SNMP_FREE */
        }
        else {
            if (PMLP_RC_STOP_PROCESSING != rc )
                snmp_log(LOG_ERR, "unknown rc %d from text processor\n", rc);
            break;
        }
    }
    SNMP_FREE(mem);
}

/*------------------------------------------------------------------
 *
 * Test line process helper functions
 *
 */
/**
 * @internal
 * process token value index line
 */
int
_process_line_tvi(netsnmp_line_info *line_info, void *mem,
                  struct netsnmp_line_process_info_s* lpi)
{
    netsnmp_token_value_index *tvi = (netsnmp_token_value_index *)mem;
    char                      *ptr;

    /*
     * get token
     */
    ptr = skip_not_white(line_info->start);
    if (NULL == ptr) {
        DEBUGMSGTL(("text:util:tvi", "no value after token '%s'\n",
                    line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }

    /*
     * null terminate, search for value;
     */
    *(ptr++) = 0;
    ptr = skip_white(ptr);
    if (NULL == ptr) {
        DEBUGMSGTL(("text:util:tvi", "no value after token '%s'\n",
                    line_info->start));
        return PMLP_RC_MEMORY_UNUSED;
    }

    /*
     * get value
     */
    switch((int)(intptr_t)lpi->user_context) {

        case PMLP_TYPE_UNSIGNED:
            tvi->value.ul = strtoul(ptr, NULL, 0);
            if ((errno == ERANGE) && (ULONG_MAX == tvi->value.ul))
                snmp_log(LOG_WARNING,"value overflow\n");
            break;


        case PMLP_TYPE_INTEGER:
            tvi->value.sl = strtol(ptr, NULL, 0);
            if ((errno == ERANGE) &&
                ((LONG_MAX == tvi->value.sl) ||
                 (LONG_MIN == tvi->value.sl)))
                snmp_log(LOG_WARNING,"value over/under-flow\n");
            break;

        case PMLP_TYPE_STRING:
            tvi->value.cp = strdup(ptr);
            break;

        case PMLP_TYPE_BOOLEAN:
            if (isdigit((unsigned char)(*ptr)))
                tvi->value.ul = strtoul(ptr, NULL, 0);
            else if (strcasecmp(ptr,"true") == 0)
                tvi->value.ul = 1;
            else if (strcasecmp(ptr,"false") == 0)
                tvi->value.ul = 0;
            else {
                snmp_log(LOG_WARNING,"bad value for boolean\n");
                return PMLP_RC_MEMORY_UNUSED;
            }
            break;

        default:
            snmp_log(LOG_ERR,"unsupported value type %d\n",
                     (int)(intptr_t)lpi->user_context);
            break;
    }
    
    /*
     * save token and value
     */
    tvi->token = strdup(line_info->start);
    tvi->index = line_info->index;

    return PMLP_RC_MEMORY_USED;
}

