#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/types.h>
#include <dirent.h>   /* for DIR info */
#include <unistd.h>   /* for unlink(), etc. */
#include <string.h>

#include "shared_util.h"   /* for cs_critical_error() */
#include "shared_authenticate.h"
#include "shared_access.h"
#include "shared_cs_util.h"
#include "../custom.h"




/** splits realname into first, last
**/

void
get_first_last_names(char *realname, char *first, char *last)
{
 char *ptr;
 
 ptr = strchr(realname,' ');
 if(!ptr)
    ptr = realname;
 else
   *ptr = '\0';
  
 strncpy(first, realname, MAX_NAME + 1);
 strncpy(last, ptr+1, MAX_NAME + 1);
 if(ptr != realname)
        *ptr = ' ';
}

    
 
int
username_invalid(char *username)
{
 char *ptr;
 
 if(!(*username))
    return 1;

 for(ptr=username; *ptr; ptr++)
   if(isspace(*ptr) || !(isalpha(*ptr) || isdigit(*ptr)) )
      return 1;
 return 0;
}

       


/** a username is the first letter of your first name,
*** followed by the first letter of your last name,
*** followed by the last LAST_N_DIGITS_OF_ID of your id
***
*** LAST_N_DIGITS_OF_ID is #defined in custom.h
**/

void
derive_username (const char *first, const char *last, 
	                const char *id, char *username, 
	                int max_username)
{



   char *ptr;
   char temp_id[MAX_ID + 1];
   char last_n_digits[MAX_ID + 1];
   int i;
      
   strncpy(temp_id, id, MAX_ID + 1);

   if(strlen(temp_id) < LAST_N_DIGITS_OF_ID)
      strcpy(last_n_digits,temp_id);
   else
     {
      ptr = strrchr(temp_id,'\0');
      for(i=1; i <= LAST_N_DIGITS_OF_ID; i++)
          ptr--;
      strcpy(last_n_digits, ptr);    
     }          
     
    *username = *first;
    *(username + 1) = *last;
    *(username + 2) = '\0';
    strcat(username, last_n_digits);
    

  /* convert username to lowercase */
   for(ptr=username; *ptr ;ptr++)
       *ptr=tolower(*ptr);

}




/** additional usernames are derived by adding 
*** additional letters from the user's last name
**/

void
derive_another_username(const char *first, const char *last, 
                           const char *id,  char *username, 
                           int string_len,  int try)
{
  char temp_id[MAX_ID +1];
  char temp_last[MAX_NAME + 1];
  int i;
  char *ptr;
  char last_n_digits[MAX_ID + 1];

  
   strncpy(temp_id, id, MAX_ID + 1);

   if(strlen(temp_id) < LAST_N_DIGITS_OF_ID)
      strcpy(last_n_digits,temp_id);
   else
     {
      ptr = strrchr(temp_id,'\0');
      for(i=1; i <= LAST_N_DIGITS_OF_ID; i++)
          ptr--;
      strcpy(last_n_digits, ptr);    
     }          
     
     
 /* save try + 1 chars of last name as temp_last */
  strncpy(temp_last, last, MAX_NAME + 1);

  /* if there aren't enough chars in last name, 
  ** return an empty username
  **/
  if((int)strlen(temp_last) < (try + 1))
      *username = '\0';
  else
   {    
    ptr = temp_last + try + 1;
    *ptr = '\0';   
     
  
    snprintf(username, MAX_USERNAME + 1, "%c%s%s", *first, temp_last, last_n_digits);
    *(username + MAX_USERNAME) = '\0';   /* make sure it's null terminated */
  
    /* convert username to lowercase */
     for(ptr=username; *ptr; ptr++)
        *ptr=tolower(*ptr);
   }      
}



void
derive_password (const char *username, const char *first_name, 
                     const char *last_name,
                        const char *id, char *password, int maxlen)
{
/* assumes username is not longer than MAX_PASSWORD! */

  strncpy(password,username, MAX_PASSWORD + 1);
  *(password + MAX_PASSWORD) = '\0';   /* make sure it's null terminated */
}


/** returns the name of the subdirectory within the
*** central user directory where username directory
*** resides
**/
char 
sub_dir_name( const char *username)
{
  return *username;
}



int
username_cmp (USER_DATA *a_data, USER_DATA *b_data)
{
  return strcmp(a_data->lastname, b_data->lastname);
}


/** converts say c402.ac20202.key to c402/ac20202 */

static
void get_course_name_from_key(const char *keyname, char *course)
{
 char *ptr;
 
 strncpy(course,keyname, MAX_FILENAME + 1);
 
 ptr = strrchr(course,'.');
 if(ptr)
   *ptr = '\0';    /* strip off .key ending */
   ptr = strchr(course,'.');
   while(ptr)    /* replace remaining dots with forward slashes */
    {
      *ptr = '/';
      ptr = strchr(course,'.');
    }  
}     





/* a key is in capture mode if the alias setting stored in the 
** key matches the ACCESS_CAPTURE_FLAG as #defined in shared_access.h
** AND if the course config access value is set to ACCESS_CAPTURE
*/
static
int capture_mode(const char *keypath, const char *keyname)
{
 SESSION user;
 FILE *fp;
 char course[MAX_FILENAME + 1];
 CONFIG_STRUCT conf;
  
 fp = fopen(keypath, "r");
 if(!fp)
   return 0;
 if(fread(&user, sizeof(SESSION), 1, fp) != 1)   
  {
   fclose(fp);
   return 0;
  }
  fclose(fp);
   
  if(!user_capturing(&user))   /* shared_access.c */
       return 0;
            
  get_course_name_from_key(keyname, course);
  if(!read_configuration_file_ok(course,&conf))   /* shared_util.c */
       return 0;
  return conf.access == ACCESS_CAPTURE;
}

       

/** deletes all central key files for username 
*** eg. deletes ../users/s/snarmont/c402.ac20202.key
*** but only if the key is not in 'capture mode'
**/

void
delete_central_user_keys(const char *username)
{
  char keydir[MAX_PATH + 1];
  DIR *dir_p;
  struct dirent *dir_entry_p;
  char keyfile[MAX_PATH + 1];
  char *ptr;  

  snprintf(keydir, MAX_PATH + 1, "../%s/%c/%s",
                            USERS_DIR, sub_dir_name(username), username);
  dir_p = opendir (keydir);
  if (!dir_p)
       cs_critical_error ( ERR_OPENDIR_FAILED, ""); 

  while (NULL != (dir_entry_p = readdir (dir_p)))
    {
      ptr = strrchr(dir_entry_p->d_name, '.');
      if(ptr && !strcmp(ptr, KEY_FILE_EXTENSION))  /* if filename ends in KEY_FILE_EXTENSION */
       {

         snprintf (keyfile, MAX_PATH + 1, "%s/%s", keydir, dir_entry_p->d_name);
         if(!capture_mode(keyfile, dir_entry_p->d_name))
               unlink(keyfile);
       }  
    }

  closedir (dir_p);
} 


/* deletes the one key for 'course' in 'username's' directory
*/

void
delete_course_central_user_key(const char *username, const char *course)
{
char modified_course[MAX_PATH + 1];
char keypath[MAX_PATH + 1];

  course_slash_to_dot(course, modified_course);    /* shared_util.c */

  snprintf(keypath, MAX_PATH + 1, "../%s/%c/%s/%s%s",
                            USERS_DIR, sub_dir_name(username), username,modified_course, KEY_FILE_EXTENSION);
  unlink(keypath);
}
  




char *get_lastname(const char *real_name)
{
    char *lastname, *ptr = 0;
    char temp_real[MAX_NAME +1];

    strncpy(temp_real, real_name, MAX_NAME+1 );
    lastname = (char *)malloc(sizeof(char)* (MAX_NAME+1));
    ptr = strrchr(temp_real, ' ');
    if(!ptr)
    {
      strncpy(lastname, temp_real, MAX_NAME +1);
    }
    else
    {
        *ptr = '\0';
        ptr++;
        strncpy(lastname, ptr, MAX_NAME +1);
    }
    return lastname;
}

