#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>

#include "../global.h"

#include "shared_util.h"   /* file_exists() */
#include "shared_authenticate.h"
#include "shared_user_index.h"
#include "shared_add_util.h"
#include "shared_lock.h"
#include "shared_central_user.h"
#include "shared_strtrm.h" /* for strtrm() */
#include "shared_file_util.h"  /* for file_exists() */
#include "shared_encrypt.h"
#include "shared_access.h"
#include "shared_cs_util.h"




/** returns realname for person represented by username
*** realname is an empty string if data can't be read
**/

void
get_central_user_realname (const char *username, char *realname)
{
 FILE *fp;
 char line[200];
 char id_fname[MAX_PATH + 1];
 char dir;
 
 *realname = '\0';
 
  dir = sub_dir_name(username);
 
 
  snprintf(id_fname, MAX_PATH + 1,
              "../%s/%c/%s/%s", USERS_DIR, dir, username,ID_FNAME);


 fp = fopen(id_fname,"r");
 if(!fp)
     return;
 if(!fgets(line,200,fp))
  {
   fclose(fp);
   return;
  } 

 
  if(!fgets(line,200,fp))
   {
      fclose(fp);
      return;
   }   
  strtrm(line);   /*shared_strtrm.c */
  strncpy(realname,line,MAX_NAME + 1);
  
  fclose(fp);
}  


/** fills in user struct with available values
*** from the central user store
*** set_capture is used for capture mode */
void
get_central_user_info (const char *username, SESSION *user, int set_capture_flag)
{
 FILE *fp;
 char line[200];
 char id_fname[MAX_PATH + 1];
 char dir;
 
  dir = sub_dir_name(username);
 
 
  snprintf(id_fname, MAX_PATH + 1,
              "../%s/%c/%s/%s", USERS_DIR, dir, username,ID_FNAME);


 fp = fopen(id_fname,"r");
 if(!fp)
   cs_critical_error(ERR_FOPEN_READ_FAILED,"");
 if(!fgets(line,200,fp))
  {
   fclose(fp);
   cs_critical_error (ERR_FREAD_FAILED, ""); 
  } 

  strtrm(line);  /* shared_strtrm.c */
  strncpy(user->id,line,MAX_ID + 1);
 
  if(!fgets(line,200,fp))
   {
      fclose(fp);
      cs_critical_error (ERR_FREAD_FAILED, ""); 
   }   
  strtrm(line);   /*shared_strtrm.c */
  strncpy(user->realname,line,MAX_NAME + 1);
  
  fclose(fp);
  strncpy(user->username, username, MAX_USERNAME + 1); 


  if(set_capture_flag)   /* then alias gets a special value */
      strcpy(user->alias, ALIAS_CAPTURE_FLAG);    /* shared_access.h */
  else
     strcpy(user->alias,"anonymous");


  /* remaining data items are not used for central user
  ** but let's give them some reasonable values anyway
  */


  user->team = 'A';
  user->group = STUDENT;
}  





int create_central_letter_dir (char letter)
{
 char letter_dir[MAX_PATH + 1];

 snprintf(letter_dir, MAX_PATH + 1, "../%s/%c", USERS_DIR, letter);
 if(!file_exists(letter_dir))  /* shared_file_util.c */
  {
   if(mkdir(letter_dir, 0770))
       return 0;
  }
 return 1;
}



int create_central_user_dir(const  char *username)
{
 char dir_name[MAX_PATH + 1];
 char dir;
 
 dir = sub_dir_name(username); 
 snprintf(dir_name, MAX_PATH + 1, 
           "../%s/%c/%s", USERS_DIR, dir, username);
 

if(mkdir(dir_name, 0770))
  return 0;
  
 return 1;  

}








int write_central_id_file (const char *realname, 
					const char *username, 
		  		           const char *id)
{
 char id_fname[MAX_PATH + 1];
 FILE *fp;
 char dir;

 dir = sub_dir_name(username); 
 snprintf(id_fname, MAX_PATH + 1,
              "../%s/%c/%s/%s", USERS_DIR, 
              			dir, username,ID_FNAME);
 fp = fopen(id_fname, "w");
 if(!fp)
       return 0;
 fprintf(fp, "%s\n%s\n", id,realname); 
 fclose(fp);
 
 return 1;
}




static 
int course_already_listed(const  char *username, 
				 const char *crs)
{
   char path[MAX_PATH + 1];
   char line[200];
   FILE *fp;
   char dir;

   dir = sub_dir_name(username);
   snprintf(path, MAX_PATH + 1, 
               "../%s/%c/%s/%s",  USERS_DIR, dir, 
                               username,COURSE_LIST_FNAME);
    fp = fopen(path,"r");
    if(!fp)
      return 0;
    if(get_shared_lock(fileno(fp), 0))
    {
	fclose(fp);
	return 0;
    }
   while(fgets(line,200,fp))
   {
    strtrm(line);   /* shared_strtrm.c */
    if(!strcmp(line,crs))
    {
     release_lock(fileno(fp));
     fclose(fp);
     return 1;
    }
   }
  release_lock(fileno(fp));
  fclose(fp);
  return 0;
}					





int add_course(const  char *username, 
		       const char *crs)
{
char path[MAX_PATH + 1];
FILE *fp;
char dir;
 dir = sub_dir_name(username);
 snprintf(path, MAX_PATH + 1, 
               "../%s/%c/%s/%s", USERS_DIR, dir, 
                               username,COURSE_LIST_FNAME);
 fp = fopen(path,"a");
 if(!fp)
    return 0;
 get_exclusive_lock(fileno(fp), 1);
 fprintf(fp,"%s\n",crs);
 release_lock(fileno(fp));
 fclose(fp);
 
 return 1;
}					




int
update_central_course_file( const char *username,
                                       const char *crs)
{
  if(!course_already_listed(username,crs))
    return add_course(username,crs);
  
  return 1;  
}    









/* return NEW_USER if userid is new
   return EXISTING_USER if userid already exists && id == id
   return CONFLICT if userid already exists but id !=id  */

USER_STATUS
central_user_status ( const char *username, const char *id)
{
 DIR *dir_ptr;
 FILE *fp;
 char directory_name[MAX_PATH +1];
 char id_file[MAX_PATH +1];
 char id_line[MAX_ID + 1];
 char dir;

 dir = sub_dir_name(username);
 snprintf(directory_name, MAX_PATH +1, 
               "../%s/%c/%s", USERS_DIR, dir, username);
 dir_ptr = opendir(directory_name);
 if(!dir_ptr)         
   return NEW_USER;
 else     /* username already exists */
 {
  closedir(dir_ptr);
  snprintf(id_file, MAX_PATH + 1, 
                "../%s/%c/%s/%s", USERS_DIR, dir, username,ID_FNAME);
  fp = fopen(id_file, "r");
  if(!fp)
      return (ERROR);
   
  if (!fgets (id_line, MAX_ID + 1, fp))
    {  
      fclose(fp);
      return (ERROR);
    }
  fclose(fp);    
  strtrm(id_line);   /* shared_strtrm.c */

  if( !strcmp(id_line, id))   /* id == id */
   return EXISTING_USER;
  else
   return CONFLICT;                  /* id !=id */
 }
}





/* returns true if a central directory exists for 'username'
*/
int
central_username_exists ( const char *username)
{
 DIR *dir_ptr;
 char directory_name[MAX_PATH +1];
 char dir;

 dir = sub_dir_name(username);   		/* shared_authenticate.c */
 snprintf(directory_name, MAX_PATH +1, 
               "../%s/%c/%s",  USERS_DIR, dir, username);
 dir_ptr = opendir(directory_name);
 if(!dir_ptr)         
   return 0;      /* no directory exists, so the username doesn't exist */
 else
  {
   closedir(dir_ptr);
   return 1;     /* the username is in use */
  }   
}



/* return NEW_USER if userid is new
   return EXISTING_USER if userid already exists && id == id
   return CONFLICT if userid already exists but id !=id  */

USER_STATUS
check_central_username ( const char *username, const char *id)
{
 DIR *dir_ptr;
 FILE *fp;
 char directory_name[MAX_PATH +1];
 char id_file[MAX_PATH +1];
 char id_line[MAX_ID + 1];
 char dir;

 if(!strlen(username))
    return CONFLICT;
    
 dir = sub_dir_name(username);
 snprintf(directory_name, MAX_PATH +1, 
               "../%s/%c/%s",  USERS_DIR, dir, username);
 dir_ptr = opendir(directory_name);
 if(!dir_ptr)         
   return NEW_USER;
 else     /* username already exists */
 {
  closedir(dir_ptr);
  snprintf(id_file, MAX_PATH + 1, 
                "../%s/%c/%s/%s",  USERS_DIR, dir, username,ID_FNAME);
  fp = fopen(id_file, "r");
  if(!fp)
    cs_critical_error(ERR_FOPEN_READ_FAILED, ""); 
   
  if (!fgets (id_line, MAX_ID + 1, fp))
    {
     fclose(fp);
     cs_critical_error (ERR_FGETS_FAILED, "");
    }
    
  fclose(fp);   
  strtrm(id_line);   /* shared_strtrm.c */

  if( !strcmp(id_line, id))   /* id == id */
   return EXISTING_USER;
  else
   return CONFLICT;                  /* id !=id */
 }
}




