#include <stdio.h>
#include <sys/file.h>      
#include <string.h>

#include "global.h"


#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_super_util.h"
#include "manhat-lib/shared_authenticate.h"
#include "manhat-lib/shared_lock.h"
#include "manhat-lib/shared_server_string.h"
#include "manhat-lib/shared_login_logs.h"
#include "manhat-lib/shared_strtrm.h"
#include "manhat-lib/shared_time.h"
#include "manhat-lib/shared_cs_util.h"

#define NUMBER_OF_OS 8 
#define NUMBER_OF_BROWSER 8 

typedef struct data_count
{
	char data[MAX_PATH +1];
	int count;
	struct data_count *next;
} DATA_COUNT;



const char *operating_system[NUMBER_OF_OS] =
    { "Mac", "Linux", "Windows NT 6.", "Windows NT 5.", "Windows NT 4.0",  "Windows 98", "Win98","Others"};
  
      
    
const char *operating_system_bre[NUMBER_OF_OS] =
    { "Mac", "Linux", "Vista", "Win XP", "WinNT 4.0",  "Wins 98", "Win98","Others"};

const char *browser[NUMBER_OF_BROWSER]={ "MSIE 7.","MSIE 6.", "MSIE 5.5", "MSIE 5.0", "Netscape", 
	                                 "Firefox","Safari", "Others"};
const char *browser_bre[NUMBER_OF_BROWSER]={ "MSIE 7.","MSIE 6.", "MSIE 5.5", "MSIE 5.0", "Netscape",   "Firefox", "Safari", "Others"};


float
compute_percent(int total, int some)
{
	float percent;

	if(total >= some)
	{
		percent = (float)some/(float)total*100;
		return percent;
	}
	else
	{
		cs_critical_error(ERR_NUMBER_ERROR, "");
	}
	return -1;
}


/** fill the array with the strings we'll be interpreting
**/
void
initialize_data(DATA_COUNT *os_data, const char *data[], int number)
{
    int i;
    for(i = 0; i< number; i++)
    {
       strncpy(os_data[i].data, data[i], MAX_PATH+1);
       os_data[i].count =0;
    }
}

void
update_count(DATA_COUNT *os_data, int number, char *line)
{
     int j;
     char *find =0;

      for(j =0; j<number; j++) 
      {
         find = strstr(line, os_data[j].data);
         if(find)
         {
           os_data[j].count++;
	    break;
         }
      }
      if(!find)
         os_data[number-1].count++;
}




void
print_graph(const DATA_COUNT *os_data, const char *bre[], const char *title,  int number, int total, int width, int height)
{
  #define MAX_TMP_NAME 40
    int i;
    char temp[50];
    char url[MAX_PATH*2 +1];
    char name[MAX_TMP_NAME];

    url[0] = '\0';
    
    snprintf(name, MAX_TMP_NAME, "%s.width", title);
    cs_set_int_value(name, width);
    snprintf(name, MAX_TMP_NAME, "%s.height", title);
    cs_set_int_value(name, height);
    snprintf(name, MAX_TMP_NAME, "%s.scale", title);
    cs_set_int_value(name, 10);

    snprintf(url, MAX_PATH *2 +1, "g.addRow(");
    for(i =0; i<number; i++)
    {
       if(i< number-1)
        snprintf(temp, 50, "%3.1f,",  compute_percent( total, os_data[i].count));
       else
        snprintf(temp, 50, "%3.1f);",  compute_percent( total, os_data[i].count));
       strcat(url, temp);
    }
    snprintf(name, MAX_TMP_NAME, "%s.addRow", title);
    cs_set_value(name, url);
    memset(url, 0, MAX_PATH *2 +1);

    snprintf(url, MAX_PATH *2 +1, "g.setXScaleValues(");
    for(i =0; i<number; i++)
    {
       if(i< number-1)
         snprintf(temp, 50, "\"%s\",", bre[i]);
       else
         snprintf(temp, 50, "\"%s\");", bre[i]); 
       strcat(url, temp);
    }
    snprintf(name, MAX_TMP_NAME, "%s.setX", title);
    cs_set_value(name, url);
    memset(url, 0, MAX_PATH *2 +1);

    snprintf(url, MAX_PATH *2+1, "g.setLegend(");
    for(i =0; i<number; i++)
    {
       if(i< number-1)
         snprintf(temp, 50, "\"%s(%s)\",", os_data[i].data, bre[i]);
       else
         snprintf(temp, 50, "\"%s(%s)\");", os_data[i].data, bre[i]);
       strcat(url, temp);

    }
    snprintf(name, MAX_TMP_NAME, "%s.setLegend", title);
    cs_set_value(name, url);
    memset(url, 0, MAX_PATH *2 +1);

    snprintf(url, MAX_PATH *2 +1, "g.setCounts(");
    for(i =0; i<number; i++)
    {
       if(i< number-1)
         snprintf(temp, 50, "%d,", os_data[i].count);
       else
         snprintf(temp, 50, "%d);", os_data[i].count);
       strcat(url, temp);
    }
    snprintf(name, MAX_TMP_NAME, "%s.setCounts", title);
    cs_set_value(name, url);
    memset(url, 0, MAX_PATH *2 +1);
  #undef MAX_TMP_NAME 
}



       




void
set_info(const DATA_COUNT *os_data, const DATA_COUNT *browser_data, int total)
{
    
    cs_set_server_name();   /* shared_cs_util.c */
    cs_set_current_time();   /* shared_cs_util.c */
    cs_set_int_value("total", total);
    if(total)
        print_graph(os_data, operating_system_bre, "os_data", NUMBER_OF_OS,  total, 500, 300);
    if(total)
       print_graph(browser_data, browser_bre, "browser", NUMBER_OF_BROWSER,  total, 500, 300);

} 






void
get_data_from_one_log(DATA_COUNT *os_data, DATA_COUNT *browser_data, const char *logfile, int *total_user)
{
FILE *fp;
char log_file[MAX_PATH +1]; 
int i =0;
char line[MAX_PATH +1];
char *ptr, *str1, *str2 ;
int include_record;

	snprintf(log_file, MAX_PATH +1, "%s/%s", LOG_PATH, logfile);
	fp = fopen(log_file, "r");
	if(fp)
	{
	  cs_set_event_msg();
	  str1 = hdf_get_value(global_cgi->hdf, "log_event.admin_prefix", "");
	  str2 = hdf_get_value(global_cgi->hdf, "log_event.successful_login", "");

	  get_shared_lock(fileno(fp), 1);
	  while(fgets(line, MAX_PATH +1, fp))  /* reads first line - username  */
	  {
	   ptr = strstr(line,str1);
           if(ptr && (ptr == line))
                include_record = 0;
           else 
                include_record = 1;
                             
	   if(!fgets(line, MAX_PATH + 1, fp))  /* second line is event */
	        break;
	   strtrm(line);   /* shared_strtrm.c */
	   if(!strcmp(line,str2)) 
	    {        
  	
	       for(i=1; i <= 3; i++)   /* skip next three lines - time, host, ip */
                 fgets(line, MAX_PATH+1, fp);

               if(fgets(line, MAX_PATH+1, fp))  /* read browser info */
	        {
                 if(include_record)
                  {
                   (*total_user)++;
	           /* update operating system count */
                   update_count(os_data, NUMBER_OF_OS, line);
	           /* update browser count */ 
                   update_count(browser_data, NUMBER_OF_BROWSER, line);
                 }  
	        }
	    }
	   else   /* not a login event - skip entire record*/
	    {
	     for(i=1; i <=4; i++)
	        fgets(line, MAX_PATH + 1, fp); 
	    }    
	 }  
          release_lock(fileno(fp));
	 }
}




void
process_one_log(const char *key, const char *logfile)
{
 int total_user =0;
 DATA_COUNT os_data[NUMBER_OF_OS], browser_data[NUMBER_OF_BROWSER];

 initialize_data(os_data, operating_system, NUMBER_OF_OS);
 initialize_data(browser_data, browser, NUMBER_OF_BROWSER);

 get_data_from_one_log(os_data, browser_data, logfile, &total_user);
 set_info(os_data, browser_data,  total_user);
}





void
process_all_logs(const char *key)
{
int total_user =0;
int log_count;
DATA_COUNT os_data[NUMBER_OF_OS], browser_data[NUMBER_OF_BROWSER];

LOGFILE_NODE *head, *ptr;   /* shared_login_logs.h */



         head = build_logfile_list(&log_count, LOG_PATH, "log");   /* shared_login_logs.h */


        initialize_data(os_data, operating_system, NUMBER_OF_OS);
        initialize_data(browser_data, browser, NUMBER_OF_BROWSER);

        total_user = 0;
        for(ptr = head; ptr; ptr=ptr->next)
	{
           get_data_from_one_log(os_data, browser_data, ptr->filename, &total_user);
	}
	
	free_logfile_list(head);    /* shared_login_logs.c */
        set_info(os_data, browser_data,  total_user);
}



			
void
read_parameters( char *key, char *logfile)
{
     cs_get_required_parameter ("logfile", logfile, MAX_FILENAME);
     cs_get_required_parameter ("id", key, MAX_KEY);
}
		
		


int main()
{
    char key[MAX_KEY +1];
    char logfile[MAX_FILENAME +1];
    SESSION user;
    
    cs_cgi_init();
    read_parameters( key, logfile);
    validate_super_key(key, &user);
    
    if(strcmp(logfile, "all"))
         process_one_log(key, logfile);
    else
         process_all_logs(key);
    cs_cgi_display("super_login_graphs", 1);
    cs_cgi_destroy();
    return 0;
}
