#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/stat.h>
#include "IMLog.hh"
#include "IMNSMapConf.hh"

int
IMNSMapConf::get_line(
    char *buf,
    int size,
    char **curptr,
    char *line
)
{
    int line_ptr, n;
    char line_buf[MAX_LINE_LEN];
    char *ptr;

    char *p = ((0 == *curptr)?*curptr=buf:*curptr);
    char *pp = p;

    line_ptr = 0;
    line[0] = '\0';

    n = *curptr - buf;
    if (n >= size) { /* No more data to read */
        return 0;
    }
    /* get line with no space */
    while(1) {
        if (*p == '\n' || *p == '\0') {
            *p++;
            continue;
        }

        /* chop one line */
        while (*p != '\n') p++ ;
        /* pp to p is one line, just as fgets returns */
        memcpy(line_buf, pp, p-pp);
        line_buf[p-pp]='\0';

        ptr = line_buf;

        /* skip preceding space keys */
        while(*ptr && isspace(*ptr)) ptr++;

        /* if is space line, get new line */
        if (*ptr == '\n' || *ptr == '\0')
            continue;

        while(*ptr != '\n' && *ptr != '\0' && line_ptr < MAX_LINE_LEN)
            line[line_ptr++] = *ptr++;

        /* trim right space */
        while (isspace(line[line_ptr-1])) line_ptr--;
        line[line_ptr] = '\0';

        /* if the line end with '\', then continue read the next line */
        if (line[line_ptr-1] == '\\') {
            line_ptr--;
            line[line_ptr] = '\0';
            continue;
        }
        break;
    }

    *curptr = p+1 ;

    if (line[0] == '\0') return 0;
    if (line[0] == COMMENT) return -1;
    return line_ptr;
}

void
IMNSMapConf::print_core(
    IMNsMapStruct *nsm
)
{
    int i;

    for (i=0; i<count; i++) {
        LOG_DEBUG("if_name [%s] \n", nsm[i].if_name);
        LOG_DEBUG("default repository [%s] \n", nsm[i].src_entry);
        LOG_DEBUG("real repository [%s] \n", nsm[i].dest_entry);
        LOG_DEBUG("location [%s] \n", nsm[i].location);
        LOG_DEBUG(" =====================================\n");
    }
}

bool
IMNSMapConf::read_ns_map_config(
    char *buf, 
    int fsize
)
{
    char   line[MAX_LINE_LEN];
    char   *kptr, *ptr;
    int    len;
    char   *curr_ptr;

    curr_ptr = 0;
    do {
        len = get_line(buf, fsize, &curr_ptr, line);

        if (!len) break;
        if (len < 0) continue;

        if (!count){
	    nsmp = (IMNsMapStruct *)calloc(1, sizeof(IMNsMapStruct));
        } else {
	    nsmp = (IMNsMapStruct *) realloc((IMNsMapStruct *)nsmp,
                                             (count+1)*sizeof(IMNsMapStruct));
        }

        if (!nsmp)
	    return false;

        kptr = 0;

        ptr = line;
        kptr = line;

        /* Get the if_name */
        while (*ptr && !isspace(*ptr)) ptr++;
        if (*ptr) {
            *ptr = '\0';
            ptr++;
        }
        nsmp[count].if_name = (char *)strdup(kptr);

        kptr = 0;
        /* Get the default repository */
        while (*ptr && isspace(*ptr)) ptr++;
        kptr = ptr;
        while (*ptr && !isspace(*ptr)) ptr++;
        if (*ptr) {
            *ptr = '\0';
            ptr++;
        }
        nsmp[count].src_entry = (char *)strdup(kptr);

        kptr = 0;
        /* Get the real repository */
        while (*ptr && isspace(*ptr)) ptr++;
        kptr = ptr;
        while (*ptr && !isspace(*ptr)) ptr++;
        if (*ptr) {
            *ptr = '\0';
            ptr++;
        }
        nsmp[count].dest_entry = (char *)strdup(kptr);

        while (*ptr && isspace(*ptr)) ptr++;
        nsmp[count].location = (char *)strdup(ptr);

        count++;
    } while(1);

    // print_core(nsmp);

    return true;
}

bool
IMNSMapConf::load()
{
    FILE *fp;
    int fd, size, nfread;
    struct stat stat_buf;
    char *file_buf;

    fp = fopen(fname.c_str(), "r");
    if (!fp)
	return false;

    fd = fileno((FILE *)fp);
    if (fstat(fd, &stat_buf) < 0) {
	return false;
    }
    size = stat_buf.st_size;
    file_buf = (char *)calloc(size, sizeof(char));
    nfread = fread(file_buf, size, 1, fp);

    if (!read_ns_map_config(file_buf, size))
	return false;

    fclose(fp);

    return true;
}

IMNSMapConf::IMNSMapConf(
    const char *nsm_fname
)
{
    fname = nsm_fname;
    nsmp = NULL;
    count = 0;
}

IMNSMapConf::~IMNSMapConf()
{
    int i;

    for (i=0; i<count; i++) {
        if (nsmp[i].if_name) free (nsmp[i].if_name);
        if (nsmp[i].src_entry) free (nsmp[i].src_entry);
        if (nsmp[i].dest_entry) free (nsmp[i].dest_entry);
        if (nsmp[i].location) free (nsmp[i].location);
    }
    free ((IMNsMapStruct *) nsmp);
}

/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
