#include <stdio.h>
#include <string.h>
#include <dirent.h>		/* Directory information. */
#include <sys/stat.h>		/* for stat()            */
#include <unistd.h>		/* for unlink, mktmp ... */


#include "global.h"


#include "manhat-lib/shared_cs_util.h"	
#include "manhat-lib/shared_news_util.h"
#include "manhat-lib/shared_potato_util.h"
#include "manhat-lib/shared_central_user.h"
#include "manhat-lib/shared_authenticate.h"
#include "manhat-lib/shared_person_list.h" 
#include "manhat-lib/shared_login.h"
#include "manhat-lib/shared_server_locked.h"
#include "manhat-lib/shared_strtrm.h"
#include "manhat-lib/shared_cookie.h"
#include "manhat-lib/shared_encrypt.h"
#include "manhat-lib/shared_access.h"
#include "manhat-lib/shared_central_log.h"
#include "manhat-lib/shared_time.h"
#include "manhat-lib/shared_system_data.h"


static void
read_parameters ( char *course_name,
		 char *username, char *password)
{

  cs_get_optional_parameter("class", course_name, MAX_FILENAME);   /* shared_cs_util.c */

  cs_get_required_parameter("username", username, MAX_USERNAME);   /* shared_cs_util.c */
  cs_get_required_parameter("password", password, MAX_PASSWORD);   /* shared_cs_util.c */
}



static void 
check_standalone_password (const char *username, const char *password,
				CONFIG_STRUCT *conf)
{
 FILE *fp;
 char passwd_path[MAX_PATH + 1];
 char line[200];

  /* path to the individual's password file */
  snprintf (passwd_path, MAX_PATH + 1, "%s%s/%s/%s",
	                   conf->course_path, PEOPLE_DIR,username,PASSWD_FNAME);

  fp = fopen (passwd_path, "r");
  if(!fp)
    cs_critical_error(ERR_USERNAME_PASSWORD, "");     /* shared_cs_util.c */

  if (!fgets (line, 200, fp))
    cs_critical_error(ERR_USERNAME_PASSWORD, "");     /* shared_cs_util.c */

  fclose(fp);   
  
  strtrm(line);   /* shared_strtrm.c */
  if(strcmp(line,encrypted_password(password, username)))   /* shared_encrypt.c */
    cs_critical_error(ERR_USERNAME_PASSWORD, "");
}




static void
check_central_password (const char *username, const char *plaintext_password)
{
 char correct_password[MAX_ENCRYPTED_PASSWORD + 1];

 if(!get_central_user_password (username, correct_password)) /* shared_encrypt.c */
          cs_critical_error(ERR_USERNAME_PASSWORD, "");   /* shared_cs_util.c */
 
 
 if(!strlen(correct_password) || 
            strcmp(correct_password, encrypted_password(plaintext_password, username)))  /* shared_encrypt.c */
      {
        write_central_log(username,hdf_get_value(global_cgi->hdf, "log_event.wrong_password", ""),"",0);     /* shared_central_log.c */      
        cs_critical_error(ERR_USERNAME_PASSWORD, "");   /* shared_cs_util.c */
      }  
}




static void
standalone_login(const char *course, const char *username,
				const char *password, char *key,
				CONFIG_STRUCT *conf)
{
 SESSION user;
 char default_passwd[MAX_PASSWORD +1];
 char first_name[MAX_NAME + 1];
 char last_name[MAX_NAME + 1];


 read_configuration_file (course, conf);        /* shared_util.c */

 check_standalone_password (username, password, conf);
 if(!get_user_info ( username, &user, conf))    /* shared_person_list.c */
     cs_critical_error(ERR_USERNAME_PASSWORD, "");   /* shared_cs_util.c */

 
 has_write_permission(&user, conf);  /* shared_access.c - generates a critical error if this person doesn't have view access */
 
 
 create_new_key (&user, conf->course_path, key, conf->key_expire);  /* shared_login.c */

 log_this_access (username, conf->course_path,PEOPLE_DIR);    	/* shared_login.c */
 
 remove_stale_symlinks (username, course, conf->access);     	/* shared_news_util.c */
 kill_hotpotato_directory(username, conf);   			/* shared_potato_util.c */

/*** FACULTY, STUDENT #defined in global.h 
**/
if(user.group == FACULTY ||
      (system_data_int("ALLOW_STUDENT_CHANGE_PASSWORD")  && user.group == STUDENT) )
 {    
   get_first_last_names(user.realname, first_name, last_name);   				/* shared_authenticate.c */
   derive_password(username, first_name, last_name, user.id, default_passwd, MAX_PASSWORD);  	/* shared_authenticate.c */
   if(!strcmp(default_passwd, password))
       printf("Location:%s?id=%s&depass=1&crs=%s\n\n", "passwd_form", key, course);
 }
  
}




static void
central_login(const char *username, 
			const char *password, char *key)
{
 SESSION user;
 char base_dir[MAX_PATH + 1];
 char default_passwd[MAX_PASSWORD +1];
 char first_name[MAX_NAME + 1];
 char last_name[MAX_NAME + 1];

 if(!cs_set_event_msg())     				/* shared_cs_util.c */
    cs_critical_error(ERR_CANT_GET_EVENT_STRING, "in central_login()");   /* shared_cs_util.c */

 check_central_password (username, password);
 get_central_user_info ( username, &user, 0);       /* shared_central_user.c , don't set capture flag*/
 snprintf(base_dir, MAX_PATH + 1, "../%s", USERS_DIR);

 create_new_key (&user, base_dir, key,system_data_int("MAX_KEY_EXPIRE"));      /* shared_login.c */

 write_central_log(username, hdf_get_value(global_cgi->hdf, "log_event.successful_login",""), "",0);     /* shared_central_log.c */
 delete_central_user_keys(username);   /* shared_authenticate.c */

 /** ALLOW_STUDENT_CHANGE_PASSWORD is defined in system_conf_data  */ 
 //if(user.group == FACULTY ||
 //    ( system_data_int("ALLOW_STUDENT_CHANGE_PASSWORD")  && user.group == STUDENT) )
    
 // {
   get_first_last_names(user.realname, first_name, last_name);     /* shared_authenticate.c */
   derive_password(username, first_name, last_name, user.id, default_passwd, MAX_PASSWORD); /* shared_authenticate.c */
   if(!strcmp(default_passwd, password))
       printf("Location:%s?id=%s&depass=1\n\n", "passwd_form", key);
 //  }
}


void set_days_hour_min_left(int diff)
{
     int value_of_day = 86400;
     int value_of_hour = 3600;
     int value_of_minute = 60;
     char left[MAX_PATH +1];
     int days;
     int hours;
     int min;

     days = diff / value_of_day;
     hours = (diff % value_of_day) / value_of_hour;
     min = ((diff % value_of_day) % value_of_hour) / value_of_minute;

     snprintf(left, MAX_PATH +1, "%d %s %d %s %d %s left", days,
		     days <= 1 ? "day":"days",
		     hours,
		     hours <= 1 ? "hour":"hours",
		     min,
		     min <= 1 ? "minute":"minutes");
     cs_set_value("left_day_hour_min", left);


}


int check_date(char *date_str)
{
    int month, day, year;
    time_t valid_time;
    time_t now;
     
    now = time(NULL);
    strtrm(date_str);
    get_month_date_year (date_str, &month, &day, &year);
    valid_time = to_time_t(month, day, year, 11, 59, 0);
    if(now <= valid_time)
    {
      set_days_hour_min_left(valid_time - now);
      return -1;      
    }
    else
      return 0;
	 
}


int  check_special_login(const char *id)
{
  FILE *fp;
  char path[MAX_PATH +1];
  char line[MAX_PATH +1];
  char date_str[MAX_PATH +1];
  int i =0;
  char *ptr;

  snprintf(path, MAX_PATH +1, "../etc/special_logins.txt");
  fp = fopen(path, "r");
  if(!fp)
    return 1;
  while(fgets(line, MAX_PATH +1, fp))
  {
     if(i == 0)
     {
	strncpy(date_str, line, MAX_PATH +1);
        cs_set_value("date", date_str); 
     }
     else
     {
	
        strtrm(line);
	if(*line == '*')
	{
	    ptr = strchr(id, line[1]);
	    if(ptr)
	    {
	      fclose(fp);
	      return 1;
	    }
	}
	else
	{
          if(strcmp(line, id) ==0)
	  {
	      fclose(fp);
              return 1;
	  }
	}

     }	 
     i++;
  }
  fclose(fp);
  
  return check_date(date_str);


}



int check_restrict_login(const char *username)
{
#ifndef WNEC_RESTRICT_LOGINS
	return 1;
#endif	
 
   int flag = 0; 


   flag = check_special_login(username);
   return flag; 
   
   
}


int
main ()
{
  char course[MAX_FILENAME + 1];
  char username[MAX_USERNAME + 1];
  char password[MAX_PASSWORD + 1];
  char key[MAX_KEY + 1];
  CONFIG_STRUCT conf;
  int flag;

  cs_cgi_init();		/* shared_cs_util.c */
  check_lockout ("", "");	/* shared_server_locked.c - server shut down? */

  read_parameters ( course, username, password);

    

  if(strlen(course))
  {
    standalone_login(course,username,password,key,&conf);
    if(system_data_int("COOKIES_ENABLED"))   /* shared_system_data.h */
     {
       set_cookie(key, system_data_str("ALIAS"),"");   /* shared_cookie.c */
       printf ("Location: %s?crs=%s&id=%s\n\n", "check_cookie", course, key);
     }
    else 
       printf ("Location: %s?crs=%s&id=%s\n\n", "main_menu", course, key);
  }
  else
  {
    flag =check_restrict_login(username);
    if( flag == -1 || flag == 1)
    {
     central_login(username, password, key);
     if(system_data_int("COOKIES_ENABLED"))   /* shared_system_data.h */
     {    
        set_cookie(key, system_data_str("ALIAS"),"");   /* shared_cookie.c */
        printf ("Location: %s?id=%s&host=%s\n\n", "check_cookie", key, hdf_get_value(global_cgi->hdf, "CGI.RemoteHost","???"));
     }
     else 
     {
        if(flag == 1)
	{
         printf ("Location: %s?id=%s&host=%s\n\n", "mymanhattan", key, hdf_get_value(global_cgi->hdf, "CGI.RemoteHost","???"));
        } 
	else 
	{
	   cs_set_value("id", key);
	   cs_set_value("host", hdf_get_value(global_cgi->hdf, "CGI.RemoteHost","???"));
	   cs_cgi_display("login", 0);
	}
     }
	  
    }
    else   
       cs_cgi_display("login", 0);
  } 
  cs_cgi_destroy(); /* shared_cs_util.c */
  return 0;
}

