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

#include "global.h"


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


typedef struct log_data
    {
        char *username;
	char *event;
	char * time;
	char *host;
	char *ip;
	char *browser;
        struct log_data *next;

    }LOG_DATA;


#define SHOW_ADMIN_FLAG "__admin__"


void
free_log_data(LOG_DATA *head)
{
    LOG_DATA *ptr, *start;
    if(head)
    {
      start = head->next;

      while(start)
      {
	 ptr = start->next;

        if(start->username)
	   free(start->username);
	if(start->event)
	   free(start->event);
	if(start->time)
	   free(start->time);
	if(start->host)
	   free(start->host);
	if(start->ip)
	   free(start->ip);
	if(start->browser)
	   free(start->browser);
	free(start);
	start = ptr;
      }
       free(head);
    }
}
      


static
int is_admin_record(const char *line)
{
 char *ptr;
 char *str;
 str = hdf_get_value(global_cgi->hdf, "log_event.admin_prefix", ""); 
 ptr = strstr(line, str);
 return (ptr && (ptr == line))? 1 : 0;
} 


LOG_DATA *
build_data_list( const char *logfile, const char *username, int *count)
{
	FILE *fp;
	char log_file[MAX_PATH +1]; 
	char line[MAX_PATH +1];
	int i =0;
	int show_admins;
        LOG_DATA *head = 0, *current =0, *ptr=0, *tail =0;


        *count = 0;

	cs_set_event_msg();
        /* if username is SHOW_ADMIN_FLAG, show all administrator activities */
        show_admins = !strcmp(username,SHOW_ADMIN_FLAG)? 1 : 0;
        
        	   
	snprintf(log_file, MAX_PATH +1, "%s/%s", LOG_PATH, logfile);
	fp = fopen(log_file, "r");

     
       if(fp)
       {
	head = (LOG_DATA *)malloc(sizeof(LOG_DATA)); /* dummy head */
	head->next =0;
	get_shared_lock(fileno(fp), 1);
	while(fgets(line, MAX_PATH +1, fp))
	{
	  strtrm(line);
	  if(strlen(username)>0)
	  {
             	
	    if(i ==0 && 
	       (!strcmp(line, username)  ||                /* username matches exactly */
	        (show_admins && is_admin_record(line))))   /* or we're looking for admins and this is an
	                                                      administrator's record */
	    {
               (*count)++;	      
               ptr = (LOG_DATA *)malloc(sizeof(LOG_DATA));
	       ptr->next =0;
	       ptr->username = malloc_str(line);
	       while(i<=4)
	       {
		 if(fgets(line, MAX_PATH +1,fp))
		 {
	           strtrm(line);
		   if(i ==0)
		     ptr->event = malloc_str(line);
                   else if (i == 1)
                     ptr->time = malloc_str(line);
	           else if(i ==2)
		     ptr->host = malloc_str(line);
	           else if(i ==3)
		     ptr->ip = malloc_str(line);
                  else if (i ==4)
	            ptr->browser = malloc_str(line);
		 }
		i++;
	       }
              i =0;
	      if(!tail)
	      {
		tail = ptr;
		current = ptr;
		head->next = ptr;
	      }
	      else
	      {
		 head->next = ptr;
		 ptr->next = current;
		 current = head->next;
	      }

	    }
	  }
	  else
	  {
	    if((*count) ==0 )
		(*count)++;

	    if(i ==6)
	    {
		(*count)++;
		i =0;
	    }
           if(i ==0)
	   {
               ptr = (LOG_DATA *)malloc(sizeof(LOG_DATA));
	       ptr->next =0;
	   }
	    if(i ==0)
		ptr->username = malloc_str(line);
	    else if( i ==1)
		ptr->event = malloc_str(line);
	    else if( i ==2)
               ptr->time = malloc_str(line);
	    else if(i ==3)
		ptr->host = malloc_str(line);
	    else if(i ==4)
		ptr->ip = malloc_str(line);
            else if (i ==5)
	      ptr->browser = malloc_str(line);
	    i++;
	    if(i ==6)
	    {
	      if(!tail)
	      {
		tail = ptr;
		current = ptr;
		head->next = ptr;
	      }
	      else
	      {
		 head->next = ptr;
		 ptr->next = current;
		 current = ptr;
	      }
	    }

	  }
	}
	release_lock(fileno(fp));
	fclose(fp);
       }
	return head;
}

void
set_data_list(LOG_DATA *head, int *i)
{
   #define MAX_TMP_NAME 50
   char name[MAX_TMP_NAME];
    LOG_DATA *ptr;
    if(head)
    {
      for(ptr = head->next; ptr; ptr = ptr->next)
      {
	  snprintf(name, MAX_TMP_NAME, "record.%d.username", *i);
          cs_set_value(name,  ptr->username);
	  snprintf(name, MAX_TMP_NAME, "record.%d.event", *i);
          cs_set_value(name,  ptr->event);
	  snprintf(name, MAX_TMP_NAME, "record.%d.time", *i);
          cs_set_value(name,  ptr->time);
	  snprintf(name, MAX_TMP_NAME, "record.%d.host", *i);
          cs_set_value(name,  ptr->host);
	  snprintf(name, MAX_TMP_NAME, "record.%d.ip", *i);
          cs_set_value(name,  ptr->ip);
	  snprintf(name, MAX_TMP_NAME, "record.%d.browser", *i);
          cs_set_value(name,  ptr->browser);
          (*i)++;
     }
    }

   #undef MAX_TMP_NAME 
}
        
void
print_one_log_data(const char *key, const char *logfile, const char *username)
{
    int count =0;
    LOG_DATA *head;
    int i =0;
    
    head = build_data_list(logfile, username, &count);
    set_data_list(head, &i);
    cs_set_int_value("num_record", count);
    free_log_data(head);
}

void
print_all_log_data(const char *key, const char *username)
{
   LOGFILE_NODE *loglist_head, *ptr;   /* shared_login_logs.h */
   int total_records =0;
   int log_count;
   int count;
   LOG_DATA *head;
   int i =0;


   loglist_head = build_logfile_list(&log_count, LOG_PATH, "log");   /* shared_login_logs.c */
   
   count = 0;
   for(ptr = loglist_head; ptr; ptr=ptr->next)
     {    
       head = build_data_list( ptr->filename, username, &count);
       set_data_list(head, &i);
       free_log_data(head);
       total_records += count;
       count = 0;
    }
    free_logfile_list(loglist_head);   /* shared_login_logs.c */
    cs_set_int_value("num_record", total_records);
}


			
void
read_parameters( char *key, char *logfile,  char *username, int *csv_file)
{
 char tmp[3];
 
     cs_get_required_parameter ("logfile", logfile, MAX_FILENAME);
     cs_get_required_parameter ("id", key, MAX_KEY);
     cs_get_optional_parameter ("username",username, MAX_USERNAME);
     cs_get_optional_parameter ("csv", tmp, 2);
     *csv_file = (*tmp == '1');
     
}
		
		


int main()
{
    char key[MAX_KEY +1];
    char logfile[MAX_FILENAME +1];
    char username[MAX_USERNAME +1];
    int csv_file;

    SESSION user;
    cs_cgi_init();
    read_parameters( key, logfile, username, &csv_file);
    validate_super_key(key, &user);

    if(strcmp(logfile, "all"))
        print_one_log_data(key, logfile, username);
    else
        print_all_log_data(key, username);
        
    cs_set_int_value("send_csv_file", csv_file? 1 : 0);
        
    cs_cgi_display("super_log_data", 1);
    cs_cgi_destroy();
    return 0;
}
