#include <stdio.h>
#include <string.h>
#include <time.h>


#include "global.h"


#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_access.h"
#include "manhat-lib/shared_search_profile.h"
#include "manhat-lib/shared_person_list.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_teamstring.h"


#define SEARCH_MIN_CHARS 2   /* user must type in at least this number of characters in the search box **/
#define MAX_MATCHES 500      /* only this number of matches will be shown */




/** sets the data items needed to present the search form ***/

void
set_form_data(  char *key,  char *crs, CONFIG_STRUCT *conf,  char *group, SESSION *user)
{
   cs_set_value("form.id", key);
   cs_set_value("form.crs", crs);

   cs_set_value("form.group", group);
   cs_set_int_value("form.field", 0);
   cs_set_int_value("form.users", 0);
   cs_set_int_value("form.results", 1);
   cs_set_int_value("form.sensitive", 0);
   cs_set_int_value("form.sort", 0);
   cs_set_int_value("form.where", 0);
   cs_set_int_value("form.oper", 1);

   cs_set_int_value("minimum_search_len", SEARCH_MIN_CHARS);
   cs_set_int_value("maximum_search_len", MAX_NAME);

   if(user->group == ADMIN || ALLOW_TEACHER_SELECT_USER_BY_COURSE)
      cs_set_int_value("include_course_search_form", 1);
    
   if(strcmp(group, "student")==0) 
     {
       cs_set_value("add_type", "student");
       cs_set_value("default_team", "A");
     }  
   else
     {
      cs_set_value("add_type", "faculty");
      cs_set_value("default_team", "Z");
     } 

}



static
void show_search_results(const char *key, const char *crs, const char *group,
	       	PROFILE_NODE *profile_head, int user_count, 
                const char *search, int field, int users,  int sensitive,
                 int where, int sort, CONFIG_STRUCT *conf)
{
#define MAX_TMP_NAME 30
 PROFILE_NODE *ptr;
 int search_len;
 int count;
 P_NODE *head, *found_ptr;
 char name[MAX_TMP_NAME];
 char url[MAX_PATH +1];

 
  search_len = strlen(search);
  if(user_count >0)
    cs_set_int_value("user_count", user_count); 

  if(user_count >0 && user_count > MAX_MATCHES)
    cs_set_int_value("max_matches_exceeded", MAX_MATCHES); 

  if(profile_head)
  {
   head  = build_option_person_list (conf);   /*shared_person_list.c */
   for(ptr = profile_head, count = 0; ptr && (count < MAX_MATCHES) ; ptr=ptr->next, count++)
   {
       for(found_ptr = head; 
                found_ptr && strcmp(found_ptr->data.username, ptr->person.username); 
                                                     found_ptr=found_ptr->next);
        

       snprintf(name, MAX_TMP_NAME, "user.%d.in_class", count);
       cs_set_int_value(name, found_ptr? 1: 0); 

      if(found_ptr)
       {
           snprintf(name, MAX_TMP_NAME, "user.%d.password_file_url", count);
	   snprintf(url, MAX_PATH +1, "%s?id=%s&amp;crs=%s&amp;open=1&amp;username=%s", "admin_list_passwd", key, crs,ptr->person.username);
	   cs_set_value(name, url); 

           snprintf(name, MAX_TMP_NAME, "user.%d.team", count);
	   snprintf(url, MAX_PATH +1, "%c", found_ptr->data.team);
	   cs_set_value(name, url); 

       }
       snprintf(name, MAX_TMP_NAME, "user.%d.username", count);
       cs_set_value(name, ptr->person.username);
       snprintf(name, MAX_TMP_NAME, "user.%d.realname", count);
       cs_set_value(name, ptr->person.realname);
       snprintf(name, MAX_TMP_NAME, "user.%d.id", count);
       cs_set_value(name, ptr->person.id);
      if(search_len) 
       {
         /* set_highlighted() is in shared_search_profile.c */
         set_highlighted(ptr->person.username, ptr->username_match, search_len, "display_username", count);
         set_highlighted(ptr->person.realname, ptr->realname_match, search_len, "display_realname", count);
         set_highlighted(ptr->person.id, ptr->id_match, search_len, "display_id", count);
        }
      
    } /* for .. */    
    free_option_person_list(head);   /* shared_person_list.c */           
  }  /* if profile_head */
#undef MAX_TMP_NAME 
} 		





void
do_action( char *key,  char *crs,  char *group,
		 char *oper, CONFIG_STRUCT *conf, const char *search, 
		int field, int users, int results, int sensitive, int where, 
		int sort, SESSION *user, int start_record, int records_per_page)
{
    PROFILE_NODE *profile_head;
    int user_count;
    char url[MAX_PATH +1];

    /* set the url for the back button */
    snprintf(url, MAX_PATH +1, "%s?id=%s&amp;crs=%s", "admin_main_menu", key, crs);
    cs_set_value("back_url", url);

    /* set basic course info, and current time */
    cs_set_course_info(conf);   /* shared_cs_util.c */
    cs_set_current_time();      /* shared_cs_util.c */
    
    /* set the data items needed to present the search form */
    set_form_data(key, crs, conf, group, user);
    
    if(*oper)   /* if oper is not blank, we've got to show the results of a search */
    {
      profile_head = build_profile_list(search, sensitive, where, field, users, sort, start_record, records_per_page, &user_count);  /* shared_search_profile.c */
      if(user_count)
       {
         cs_set_team();
         show_search_results(key, crs, group,profile_head,  user_count, search,  field,  users,sensitive,where,  sort, conf);
         free_profile_list(profile_head);   /* shared_search_profile.c */
       }  
         
      /** ALLOW_TEACHER_CREATE_NEW_ACCOUNT is #defined in custom.h **/   
      if(user->group == ADMIN || (ALLOW_TEACHER_CREATE_NEW_ACCOUNT && user->group==FACULTY))
      {
              cs_set_int_value("show_new_form", 1);
	      cs_set_int_value("max_id", MAX_ID);
	      cs_set_int_value("max_name", MAX_NAME /2);
              cs_set_team();
      }
    }
    
}

int
main()
{
  char key[MAX_KEY +1];
  char crs[MAX_PATH +1];
  char group[MAX_ID +1];
  char search[MAX_PATH + 1];   /* from command line  - string to search for */
  int field;                   /* from command line - what fields to search on? */
  int users;                   /* from command line - what users to include? */
  int results;                 /* from command line - what form should results take */
  int sensitive;               /* from command line - case sensitive search? */
  int where;                   /* from command line - match must contain, start with, end with? */
  int start_record;
  int records_per_page;
  int sort;
  char oper[20];
  
  SESSION user;
  CONFIG_STRUCT conf;

   cs_cgi_init();
  /*shared_search_profile.c */
  read_search_parameters(key, crs, group, oper, search, &field, &users, &results,  
                                          &sensitive, &where, &sort, &start_record, &records_per_page);
  
  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 */
       cs_critical_error(ERR_REQUEST_DENIED, "");

  if ( (user.group == FACULTY) || (user.group == ADMIN))
   {
        if(strlen(oper) && (strlen(search) < SEARCH_MIN_CHARS))  /* #defined at top of this file */
            cs_critical_error(ERR_SEARCH_STRING_TOO_SHORT, search);
        else    
	{
            do_action(key, crs, group,oper, &conf, search, 
		 field,  users,  results,  sensitive,  where,  sort, &user, start_record, records_per_page);
	}
   }	 
  else
       cs_critical_error(ERR_REQUEST_DENIED, "");

  #ifdef HIDE_MANHATTAN_USERNAMES
   cs_set_int_value("hide_manhattan_username", 1);
  #endif
       
  cs_cgi_display("admin_search_form", 1);
  cs_cgi_destroy();
  return 0;
}


