#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <stdarg.h>
#include "webtool.h"

void weblogger(char *logfile, const char *fmt, ...){
        char p[102400];
        struct stat st;
        FILE *log;
        va_list ap;
        struct timeval tv;
        struct tm _tm;
        struct tm *tm;
        char datestamp[512];
        gettimeofday(&tv,NULL);
        tm = localtime_r(&tv.tv_sec,&_tm);
        sprintf(datestamp,"[%04d-%02d-%02d %02d:%02d:%02d.%06d]{%d}",
                tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
                tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec,
                getpid());

        va_start(ap,fmt);
        vsnprintf(p,102400,fmt,ap);
        va_end(ap);

        log = fopen(logfile,"a");
        if ( log == NULL ) return;
        fprintf(log,"%s %s",datestamp,p);
        fflush(log);
        fclose(log);
}

#define WEBLOG "/big/GIX_INETD/logs/multi.log"


struct multi *webtool_multi_list;
int webtool_multis;

void webtool_process_block(unsigned char *content, int len){
	unsigned char lin[256];
	unsigned char *hlp;
	char content_type[128];
	char filename[512];
	char name[256];
	unsigned char *oldoffset;
	int position;
	int datasize;


	if ( *content == '\r' || *content == '\n' ) content++;
	if ( *content == '\r' || *content == '\n' ) content++;

	content[len] = '\0';
	weblogger(WEBLOG,"Processing block: (%d Bytes)\n",len);
	weblogger(WEBLOG,"Content: [%s]\n",content);
	hlp = content;

	bzero(name,256);
	bzero(filename,512);
	bzero(content_type,128);
	oldoffset = content;
	while ( 1 ){
		unsigned char *xptr;
		int blen;
		while ( *content && *content != '\n' ) content++;
		if ( *content == '\0' ) return;
		content++;
		blen = (int) (content - hlp);
		strncpy(lin,hlp,blen);	
		lin[blen] = '\0';
		if ( lin[strlen(lin)-1] == '\r' || lin[strlen(lin)-1] == '\n' ) lin[strlen(lin)-1] = '\0';
		if ( lin[strlen(lin)-1] == '\r' || lin[strlen(lin)-1] == '\n' ) lin[strlen(lin)-1] = '\0';
		if ( strlen(lin) == 0 ) break;
		blen = strlen(lin);
		if ( (xptr = strstr(lin,"name=")) != NULL ){
			unsigned char _cnt[256];
			unsigned char *cnt;
			bzero(_cnt,256);
			cnt = &_cnt[0];
			xptr += 5;
			strncpy(cnt,xptr,(xptr - lin)+1);
			xptr = cnt;
			while ( *xptr && !isspace(*xptr) &&  *xptr != ';' ) xptr++;
			*xptr = '\0';
			weblogger(WEBLOG,"CNT: [%s]\n",cnt);
			if ( *cnt == '\"' || *cnt == '\'' ){
				cnt++;
				if ( cnt[strlen(cnt)-1] == '\"' || cnt[strlen(cnt)-1] == '\'' )  cnt[strlen(cnt)-1] = '\0';
			}
			strcpy(name,cnt);
		}
		if ( (xptr = strstr(lin,"filename=")) != NULL ){
			unsigned char _cnt[256];
			unsigned char *cnt;
			bzero(_cnt,256);
			cnt = &_cnt[0];
			xptr += 9;
			strncpy(cnt,xptr,((int)(xptr - lin))+1);
			xptr = cnt;
			while ( *xptr && !isspace(*xptr) &&  *xptr != ';' ) xptr++;
			*xptr = '\0';
			weblogger(WEBLOG,"CNT: [%s]\n",cnt);
			if ( *cnt == '\"' || *cnt == '\'' ){
				cnt++;
				if ( cnt[strlen(cnt)-1] == '\"' || cnt[strlen(cnt)-1] == '\'' )  cnt[strlen(cnt)-1] = '\0';
			}
			if ( strlen(filename)  == 0 ) strcpy(filename,cnt);
		}
		if ( (xptr = strstr(lin,"Content-Type:")) != NULL ){
			unsigned char _cnt[256];
			unsigned char *cnt;
			bzero(_cnt,256);
			cnt = &_cnt[0];
			xptr += 13;
			while ( *xptr && isspace(*xptr) ) xptr++;
			strncpy(cnt,xptr,(xptr - lin)+1);
			xptr = cnt;
			while ( *xptr && !isspace(*xptr) &&  *xptr != ';' ) xptr++;
			*xptr = '\0';
			weblogger(WEBLOG,"CNT: [%s]\n",cnt);
			if ( *cnt == '\"' || *cnt == '\'' ){
				cnt++;
				if ( cnt[strlen(cnt)-1] == '\"' || cnt[strlen(cnt)-1] == '\'' )  cnt[strlen(cnt)-1] = '\0';
			}
			strcpy(content_type,cnt);
		}
		weblogger(WEBLOG,"LINE: [%s] BLEN: %d\n",lin,blen);
		hlp = content;
	}
	position = (int)(content - oldoffset);
	datasize = len - position;	
	/* if ( content[datasize-1] == '\r' || content[datasize-1] == '\n') */ { datasize--; content[datasize] = '\0'; }
	/* if ( content[datasize-1] == '\r' || content[datasize-1] == '\n') */ { datasize--; content[datasize] = '\0'; }
	/* if ( content[datasize-1] == '\r' || content[datasize-1] == '\n') */ { datasize--; content[datasize] = '\0'; }
	/* if ( content[datasize-1] == '\r' || content[datasize-1] == '\n') */ { datasize--; content[datasize] = '\0'; }
	weblogger(WEBLOG,"Pointing at:  [%d] Size: %d Bytes\n",position,datasize);
	weblogger(WEBLOG,"DATA:         [%s]\n",content);
	weblogger(WEBLOG,"NAME:         [%s]\n",name);	
	weblogger(WEBLOG,"FILENAME:     [%s]\n",filename);	
	weblogger(WEBLOG,"CONTENT_TYPE: [%s]\n",content_type);	

	webtool_multi_list = (struct multi *)realloc(webtool_multi_list,sizeof(struct multi) * (webtool_multis+1));
	
	webtool_multi_list[webtool_multis].size = datasize;
	webtool_multi_list[webtool_multis].content = (char *)malloc(datasize+1);
	memcpy(webtool_multi_list[webtool_multis].content,content,datasize);
	webtool_multi_list[webtool_multis].content[datasize] = '\0';
	strcpy(webtool_multi_list[webtool_multis].name,name);
	strcpy(webtool_multi_list[webtool_multis].filename,filename);
	strcpy(webtool_multi_list[webtool_multis].type,content_type);
	webtool_multis++;	
}

int load_multis(unsigned char *content,int content_length,char *_boundary){
	char *block;
	char *boundary;  
	unsigned char *ptr;
	unsigned char *eptr;
	int b_len;
	int block_len;
	int i;

	webtool_multis = 0;
	webtool_multi_list = NULL;	

	boundary = (char *)malloc(strlen(_boundary));
	sprintf(boundary,"--%s",_boundary);

	b_len = strlen(boundary);
	block = (char *)malloc(content_length+1);

	content[content_length] = '\0';
	weblogger(WEBLOG,"Content-Length: %d\n",content_length);
	weblogger(WEBLOG,"CONTENT: [\n%s\n]\n",content);
	ptr = content;
	while ( (ptr = strstr(ptr,boundary)) != NULL ){
		ptr += b_len;
		if ( strncmp(ptr,"--",2) == 0 ) break; //  End of input
		eptr = ptr;
		while ( (eptr - content) < content_length && memcmp(eptr,boundary,b_len) != 0 ) eptr++;
		if ( !*eptr ){
			weblogger(WEBLOG,"Corrupted input!\n");
			free(block);
			free(boundary);
			return(-1);
		}
		block_len = (int)(eptr - ptr);
		memcpy(block,ptr,block_len);
		webtool_process_block(block,block_len);
		ptr = eptr;
		// weblogger(WEBLOG,"Next block: [%s]\n",ptr);
	}
	free(block);
	free(boundary);
	weblogger(WEBLOG,"All blocks processed [Found: %d blocks]\n",webtool_multis);
	for ( i = 0; i < webtool_multis; i++ ){
		weblogger(WEBLOG,"[%d] NAME:     [%s]\n",i,webtool_multi_list[i].name);
		weblogger(WEBLOG,"[%d] FILENAME: [%s]\n",i,webtool_multi_list[i].filename);
		weblogger(WEBLOG,"[%d] TYPE:     [%s]\n",i,webtool_multi_list[i].type);
		weblogger(WEBLOG,"[%d] SIZE:     [%d]\n",i,webtool_multi_list[i].size);
	}
	return(webtool_multis);
}



struct multi *read_multi(char *name){
	int i;
	for ( i = 0; i < webtool_multis; i++ ){
		if ( strcmp(name,webtool_multi_list[i].name) == 0 ) return(&webtool_multi_list[i]);	
	}
	return(NULL);	
}

struct multi *read_multi_index(int idx){
	if ( idx >= webtool_multis ) return(NULL);
	return(&webtool_multi_list[idx]);	
}
