#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <ctype.h>

#include "global.h"

#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_strtrm.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_add_util.h"
#include "manhat-lib/shared_add_student.h"
#include "manhat-lib/shared_central_user.h"
#include "manhat-lib/shared_authenticate.h"
#include "manhat-lib/shared_encrypt.h"
#include "manhat-lib/shared_access.h"
#include "manhat-lib/shared_user_index.h"
#include "manhat-lib/shared_teamstring.h"
#include "manhat-lib/shared_person_list.h"



int has_space(char *string)
{
 char *ptr;
 
 for(ptr=string; *ptr; ptr++)
    if(isspace(*ptr))
       return 1;
 return 0;
}

        



int has_bad_chars(char *string)
{
#define BANNED_CHARS "/\\*?\":" 
 char *ptr;
 
 
 for(ptr = string; *ptr; ptr++)
  {
   if(!isascii(*ptr))
        return 1;
   if( (ptr == string)  && 
          isspace(*ptr) )
       return 1;
   if( !(isalpha(*ptr) || isdigit(*ptr)) )
      {
       if(strchr(BANNED_CHARS,*ptr))
           return 1;
      }
 }          
      
 return 0;
#undef BANNED_CHARS  
}

      

void
read_parameters (char *course, char *key,
		 char *first, char *last, char *student_id, char *group, char *team)
{

  cs_get_required_parameter ("crs", course, MAX_PATH);
  cs_get_required_parameter ("id", key, MAX_KEY);
  cs_get_required_parameter ("group", group, MAX_ID);
  
  cs_get_required_parameter ("first", first, MAX_NAME /2 );
  if(!strlen(first) || has_bad_chars(first))
     cs_critical_error (ERR_FIRST_NAME_HAS_INVALID_CHARS, "");
  
  cs_get_required_parameter ("last", last, MAX_NAME /2 );
  if(!strlen(last) || has_bad_chars(last))
    cs_critical_error (ERR_LAST_NAME_HAS_INVALID_CHARS, "");
  
  cs_get_required_parameter ("user_id", student_id, MAX_ID );
  if ( (strlen (student_id) < 4)  || has_bad_chars(student_id) || has_space(student_id))
    cs_critical_error (ERR_ID_HAS_INVALID_CHARS, "");

  cs_get_required_parameter ("team", team, MAX_ID );
}




static void
set_success_data ( char *username, char *plaintext_password, 
		 char *realname,
	          char *team, char *id,
	          char *course,  char *key,  char *group)
{
  char url[MAX_PATH +1];
   
  snprintf (url, MAX_PATH +1, "%s?crs=%s&amp;id=%s", "admin_main_menu", course, key);
  cs_set_value("back_url", url);
	  
  cs_set_value("username", username);
  cs_set_value("realname", realname);
  cs_set_value("id", id);
  if(strcmp(group, "student") ==0)
  {
    cs_set_value("group", "1");
    cs_set_value("add_type", "student");
  }
  else
  {
    cs_set_value("group", "0");
    cs_set_value("add_type", "faculty");
  }
  get_team_name(*team, url);
  cs_set_value("team", url);
  cs_set_value("status", "0");
  cs_set_value("passwd", plaintext_password);

}





static 
void set_new_user_form(  char *course, 
 			   char *key, 
 			   char *group,
			   char *username,
			   char *realname,
			   char *id,
			   char *team, int in_class,  char *exist_team)
{
  char url[MAX_PATH +1];
  

  snprintf (url, MAX_PATH +1, "%s?crs=%s&amp;id=%s", "admin_main_menu", course, key);
  cs_set_value("back_url", url);
  
  cs_set_value( "crs", course);
  cs_set_value( "id", key);
  cs_set_value( "group", group);
 
  cs_set_int_value("user.0.in_class", in_class);
  if(in_class)
  {
    snprintf (url, MAX_PATH +1, "%s?id=%s&amp;crs=%s&amp;open=1&amp;username=%s", "admin_list_passwd", key, course, username);
    cs_set_value("user.0.password_file_url", url);
      
  }
  cs_set_value("user.0.username", username);
  cs_set_value("user.0.realname", realname);
  cs_set_value("user.0.id",id );
  cs_set_value("user.0.display_username", username);
  cs_set_value("user.0.display_realname", realname);
  cs_set_value("user.0.display_id", id);
  
  if(strcmp(group, "student") ==0)   /* if this is a student */
  {
    cs_set_value("user.0.team", in_class ? exist_team :"A");
    cs_set_value("add_type", "student");
    cs_set_value("default_team", "A");
  }
  else
  {
    cs_set_value("user.0.team", in_class ? exist_team : "Z");
    cs_set_value("add_type", "faculty");
    cs_set_value("default_team", "Z");
  }
  cs_set_team();    /* shared_teamstring.c */
} 				



int is_new_person_in_class(const char *username, char *exist_team, CONFIG_STRUCT *conf) 
{
   P_NODE *head, *ptr;
   head = build_option_person_list(conf);
   for(ptr = head; ptr; ptr=ptr->next)
   {
         if(!strcmp(username, ptr->data.username))
	 {
              snprintf(exist_team, 3, "%c", ptr->data.team); 
              return 1;
	 }
   }
   return 0;

}	




int
main ()
{

  char username[MAX_USERNAME + 1];
  char plaintext_password[MAX_ENCRYPTED_PASSWORD + 1];
  char realname[MAX_NAME + 1];
  char first[MAX_USERNAME + 1];
  char last[MAX_USERNAME + 1];
  char group[MAX_ID +1];
  char id[MAX_ID + 1];
  char team[MAX_ID +1];

  char course[MAX_PATH + 1];	/* from crs=? command line */
  char key[MAX_KEY + 1];	/* from id=? command line */
  SESSION user;
  CONFIG_STRUCT conf;                   /* the configuration read from config file */
  char passwd_fname[MAX_PATH + 1];	/* path to the password file */
  char *buffer;
  int in_class =0;
  char exist_team[10];

  cs_cgi_init();

  read_parameters (course, key, first, last, id, group, team);
  read_configuration_file (course, &conf);	/* shared_util.c */
  validate_key (key, &user, &conf);	/* shared_util.c */
  
  if(!has_write_permission(&user, &conf))   /* shared_access.c */
     access_denied_error();                 /* shared_access.c */


  if ( ((user.group != FACULTY) && (user.group != ADMIN)) || (conf.standalone) )
       cs_critical_error (ERR_REQUEST_DENIED, "");

   /* read the entire users/index.txt file into a null-terminated buffer */
   buffer_index(&buffer);   /* shared_user_index.c */

  /* try to get the username/realname from the user/index.txt file by
   *  ** searching for a record with the same ID number
   *   */
   index_get_names(buffer, id, username,realname);  /* shared_user_index.c */

   free(buffer);

   cs_set_course_info(&conf);
   cs_set_current_time();

   if(strlen(username))  /* existing user */
   {
     in_class = is_new_person_in_class(username, exist_team, &conf);  
     set_new_user_form( course, key,  group, username, realname, id, team, in_class, exist_team);
     cs_set_int_value("existing_user", 1);
     cs_cgi_display("admin_add_new_student", 1);
   }
   else   /* add the new user */
   {
    snprintf (passwd_fname, MAX_PATH + 1, "%s%s", conf.course_path, PASSWORD_FNAME);
    get_ctr_realname (first, last, realname); /* shared_add_student.c */
    check_id (id, passwd_fname);  /* shared_add_student.c */

    if(!update_central_user (first, last, id, course, realname, username,plaintext_password))       /* shared_encrypt.c */
		     cs_critical_error(ERR_UPDATING_CENTRAL_USER, ""); 		

  /* don't test for errors on next, since directory might already exist */
    create_directories (conf.course_path, username);   /* shared_add_util.c */
  
    if(!add_to_passwd (username, realname, *team, id, passwd_fname, group)) /* shared_add_util.c */
      cs_critical_error(ERR_ADDING_TO_PASSWORD, ""); 		
      
     set_success_data (username, plaintext_password, realname, team,  id, course, key, group);
     cs_cgi_display("admin_add_new_student", 1);
   }
   
   cs_cgi_destroy();
  return 0;

} 				


