#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "global.h"
#include "custom.h"

#include "manhat-lib/shared_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_access.h"
#include "manhat-lib/shared_encrypt.h"
#include "manhat-lib/shared_add_util.h"
#include "manhat-lib/shared_search_profile.h"
#include "manhat-lib/shared_cs_util.h"

#include "manhat-lib/shared_teamstring.h"


int 
find_user_inlist(P_NODE *head, P_NODE *one_user)
{
   P_NODE *ptr;
   for(ptr = head; ptr; ptr=ptr->next)
   {
      if(!strcmp(ptr->data.username,one_user->data.username))
	      return 1;
   }
   return 0;
}



P_NODE *
new_node(const char *add, const char *group)
{
  P_NODE *ptr;
  char team[10];

   ptr = (P_NODE*)malloc(sizeof(P_NODE));
   if(!ptr)
     cs_critical_error(ERR_MALLOC_FAILED, "");
     
   if(!parse_line(add, ptr))  /* shared_search_profile.h */
     cs_critical_error(ERR_PASS_PARAMETERS_ERROR_MSG,  add);
     
   cs_get_required_parameter(ptr->data.username, team, 9);
   
   ptr->data.team = *team; 
   ptr->data.group = (strcmp(group, "student") == 0?STUDENT:FACULTY);
   ptr->next = 0;
   return ptr;
}






P_NODE *
all_users( const char *group)
{
 char *add;
 P_NODE *head =0, *current=0, *ptr;
 HDF *obj;

 add = hdf_get_value(global_cgi->hdf, "Query.users.0", 0);
 if(add)
  {
    obj = hdf_get_child(global_cgi->hdf, "Query.users");  
    while(obj)
     {
      add = obj->value;
      if(add && strlen(add))
         {
	  ptr = new_node(add, group);
          if(!head)
	        head = ptr; 
          else 
              if(!find_user_inlist(head, ptr))
	            current->next = ptr;
            current = ptr;
	  }
      obj = obj->next;
      }
  }
  else
   {
    add = hdf_get_value(global_cgi->hdf, "Query.users", 0);
    if(!add || strlen(add) ==0)
	  cs_critical_error(ERR_PARAM_MISSING, "users");
    else	  
          head = new_node(add, group);
   }
 
 return head;
}
     



      	
P_NODE *
read_parameters(char *key, char *crs, char *group)
{
    P_NODE *head;


    cs_get_required_parameter ("crs", crs, MAX_PATH);
    cs_get_required_parameter ("id", key, MAX_KEY);
    cs_get_required_parameter ("group", group, MAX_ID);

    head = all_users( group);
    if(!head)
       cs_critical_error(ERR_PARAM_MISSING,"users");
       

    return head;
}





void
add_users_to_central_course(P_NODE *head, CONFIG_STRUCT *conf, const char *crs)
{
   P_NODE *ptr;
   P_NODE *person_crs;
   char passwd_fname[MAX_PATH +1];
   char realname[MAX_NAME +1];
   char first[MAX_NAME +1];
   char last[MAX_NAME +1];
   char *sp_ptr;

   snprintf (passwd_fname, MAX_PATH + 1, "%s%s", conf->course_path, PASSWORD_FNAME);
   person_crs = build_option_person_list (conf);
   
   for(ptr = head; ptr; ptr = ptr->next)
   {
      if(!find_user_in_course(person_crs, ptr->data.username)) /*shared_search_profile.c */
      {
          /* don't test for errors on next, since directories might already exist */
         create_directories (conf->course_path, ptr->data.username);
         if(conf->standalone)
	 {
           strncpy(realname, ptr->data.realname, MAX_NAME +1);
	   sp_ptr = strchr(realname, ' ');
	   if(sp_ptr)
	      *sp_ptr = '\0';
           strncpy(first, realname, MAX_NAME +1);
	   *sp_ptr = ':';
	   sp_ptr++;
	   strncpy(last, sp_ptr, MAX_NAME +1);
	   derive_password (ptr->data.username, first, last, ptr->data.id, ptr->data.password,MAX_PASSWORD);/* shared_authenticate.c */
         }
         if(!add_to_passwd (ptr->data.username, ptr->data.realname, ptr->data.team, ptr->data.id, passwd_fname, ptr->data.group == STUDENT ? "student":"faculty")) /* shared_add_util.c */
	       cs_critical_error(ERR_ADDING_TO_PASSWORD, "");
         if(!conf->standalone)
	 {
           if(!update_central_course_file(ptr->data.username, crs)) /*shared_central_user.c */
             cs_critical_error(ERR_ADDING_COURSE_TO_USERS_LIST,"");
	 }
	 else
         {
	   if(! write_password(ptr->data.username, ptr->data.password, conf->course_path)) /* shared_add_util.c */
		   cs_critical_error(ERR_ADDING_TO_PASSWORD, "");
	 }

      }
   } 
  free_option_person_list(person_crs);
}




void
set_result_values(P_NODE *head, const char *key, const char *crs, const char *group, CONFIG_STRUCT *conf)
{
    #define MAX_TMP_NAME 30

     P_NODE *ptr;
     char url[MAX_PATH +1];
     char name[MAX_TMP_NAME];
     int i = 0;

     snprintf (url, MAX_PATH +1, "%s?crs=%s&amp;id=%s", "admin_main_menu", crs, key);
     cs_set_value("back_url", url);
     cs_set_course_info(conf);
     cs_set_current_time();

     cs_set_value("add_type", !strcmp(group,"student")?"student":"faculty");
       
     for( i = 0, ptr = head; ptr; ptr = ptr->next, i++)
     {
	 snprintf(name, MAX_TMP_NAME, "user.%d.username", i);
	 cs_set_value(name, ptr->data.username);

	 snprintf(name, MAX_TMP_NAME, "user.%d.realname", i);
	 cs_set_value(name, ptr->data.realname);

	 snprintf(name, MAX_TMP_NAME, "user.%d.id", i);
	 cs_set_value(name, ptr->data.id);

         get_team_name(ptr->data.team, url);          /* shared_teamstring.c */
	 snprintf(name, MAX_TMP_NAME, "user.%d.team", i);
	 cs_set_value(name, url);

     }
    #undef MAX_TMP_NAME 
}



void
add_users(P_NODE *head, const char *key, const char *crs,  CONFIG_STRUCT *conf, const char *group)
{

     add_users_to_central_course(head, conf,crs);
     set_result_values(head, key, crs, group, conf);
}




int main()
{
   char key[MAX_KEY +1];
   char crs[MAX_PATH +1];
   char group[MAX_ID +1];
   P_NODE *head;
   SESSION user;
   CONFIG_STRUCT conf;

   cs_cgi_init(); 


   head =  read_parameters(key, crs, group);
   read_configuration_file (crs, &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))
    add_users(head, key, crs,  &conf, group);
  else
        access_denied_error();   /* shared_access.c */

  free_option_person_list(head);

 #ifdef HIDE_MANHATTAN_USERNAMES
   cs_set_int_value("hide_manhattan_username", 1);
  #endif

  cs_cgi_display("admin_add_group_students", 1);
  cs_cgi_destroy();
  return 0;

}



