#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>  /* for mkstemp(), etc */
#include <unistd.h>  /* for symlink() */
       
#include "../custom.h"


#include "shared_lock.h"    /* for get_shared_lock() , etc */
#include "shared_util.h"   /* for cs_critical_error */
#include "shared_news_util.h"  /* for remove_stale_symlinks() */
#include "shared_file_util.h"
#include "shared_cs_util.h"
#include "shared_bb_manifest.h"


/** Reads the info file, that is, the file named info_fname in
*** sender_username's "assignments" directory.
*** Returns source_path, which is the path to the XML quiz file
*** and dirname, which is the name of the directory (within
*** sender_username's "assignments" directory) where the source file
*** can be found.
***
*** dirname is later used to create a symbolic link 
**/

void
get_hotpot_exam_source_fname (char *source_path, char *dirname, const char *course_path, 
			const char *sender_username, const char *info_fname)
{
  char infopath[MAX_PATH + 1];
  NEWS_INFO info;
  ATTACHMENT attach;
  FILE *fp;
  int fd;

  snprintf (infopath, MAX_PATH + 1, "%speople/%s/%s/%s", course_path,
	    sender_username,ASSIGNMENTS_DIR, info_fname);

  fp = fopen (infopath, "r");
  if (!fp)
    cs_critical_error (ERR_FOPEN_READ_FAILED, ""); 

  fd = fileno(fp);  
  get_shared_lock(fd,1);  /*shared_lock.c */
  
  if (fread (&info, sizeof (NEWS_INFO), 1, fp) != 1)
    cs_critical_error (ERR_FREAD_FAILED, "");
  if(info.attachments != -1)
     cs_critical_error( ERR_EXPECTED_ATTACHED_WEBSITE  , "");
     
  if (fread (&attach, sizeof (ATTACHMENT), 1, fp) != 1)
    cs_critical_error (ERR_FREAD_FAILED, "");

  release_lock(fd);    /* shared_lock.c */
  fclose (fp);
  strncpy (dirname, attach.unique_fname, MAX_FILENAME + 1);   /* unique_fname contains the name of the directory */
  snprintf(source_path,MAX_PATH+1,
                     "%speople/%s/%s/%s/%s", course_path,sender_username,ASSIGNMENTS_DIR,
                                                  attach.unique_fname, attach.orig_fname);
} 


/** writes to 'path' the full path to username's score file for the
** hotpotatoes exam sent by 'sender' represented by 'info_fname'
**/
void get_hotpot_score_path(const char *course_path, const char *username, const char *sender, const char *info_fname,
				char *path)
{
 snprintf(path,MAX_PATH + 1, "%s%s/%s/%s/%s_%s%s",course_path, PEOPLE_DIR, username,
                                                       ASSIGNMENTS_DIR,sender,info_fname, HOTPOT_EXAM_SCORE_EXTENSION);
}



time_t hotpot_time_viewed(const char *score_path)
{
 FILE *fp;
 int fd;
 time_t viewed_time;
 
 fp = fopen(score_path,"r");
 if(!fp) 
    return 0;
 fd = fileno(fp);
 get_shared_lock(fd,1);   /* shared_lock.c */
 
 if(fread(&viewed_time, sizeof(time_t), 1, fp) != 1)
     viewed_time = 0;

 release_lock(fd);
 fclose(fp);
 return viewed_time;
}         


int get_hotpot_unique_fd(const char *base_dir, const char *filetype, char *unique_fname, time_t *time_sent)
{
  char template[MAX_PATH + 1];
  char timestring[MAX_TIMESTRING + 1];
  int fd;
  char *ptr;
  
  strftime (timestring, MAX_TIMESTRING, "%m%d%Y%H%M%S",localtime (time_sent));

  snprintf (template, MAX_PATH + 1, "%s%s_%s_XXXXXX", base_dir,filetype, timestring);
  
  fd = mkstemp(template);
  if(fd == -1)
      cs_critical_error(ERR_MKSTEMP_FAILED, "");
  change_mkstemp_permission(template);  /*shared_file_util.c */
  ptr = strrchr(template,'/');
  if(!ptr)
    cs_critical_error(ERR_GENERAL_ERROR, "");
  ptr++;
  strncpy(unique_fname, ptr,MAX_FILENAME + 1);
  if(fchmod(fd,S_IWGRP|S_IRGRP|S_IRUSR|S_IWUSR))
    cs_critical_error(ERR_CHMOD_FAILED,"");
  return fd;
}  


void
get_hotpot_unique_fname(char *unique_fname, const char *base_dir, const char *filetype, time_t *time_sent)
{
 int fd;
 
 fd = get_hotpot_unique_fd(base_dir, filetype, unique_fname, time_sent);
 close(fd);
} 






/* retrieves, in 'value' item 'n' from
** the comma separated value line 'line'
** the value can't exceed maxlen
** 'n' starts from 0 as the first item
*/

int
csv_value(char *line, int n, char *value, int maxlen)
{
 char *start_ptr, *end_ptr = 0, *null_ptr;
 char tmp;
 int is_quoted;
 int count, end_found;
 
 for(count = 0; count <= n; count++)
  {
   start_ptr = !count? line : end_ptr + 1;
   if((!*start_ptr) ||  (*start_ptr == '\n')  || (*start_ptr == '\r'))
       return 1;   /* item not found */
   is_quoted = ( *start_ptr == '"');

   for(end_ptr = start_ptr + 1, end_found=0; !end_found && *end_ptr; end_ptr++)
    {
     switch(*end_ptr)
      {
       case '\0': 
       case '\n':
       case '\r':  if(is_quoted)
                         return 1;     
                   else
                     end_found = 1;      
                    break; 
       
       case ',': end_found = !is_quoted ||
                            (is_quoted && (*(end_ptr - 1) == '"'));
                 break;
       
       default:  break;
    }
   }
   
   if(!end_found)
      return 1;
  
   end_ptr--;
   if(end_ptr < line)
       return 1;
   
   /* null_ptr used to strip quotes from quoted values */
   null_ptr = is_quoted? end_ptr -1 : end_ptr;
   tmp = *null_ptr;
   *null_ptr = '\0';
   
   strncpy(value,is_quoted?start_ptr + 1: start_ptr,maxlen);
   *null_ptr = tmp;
  }         

 return 0;
}




void
create_hotpot_exam_symlink (const char *coursepath, const char *sender, const char *dirname,
                const SESSION *user, const char *crs, char *symlink_fname, int access)
{

  char oldname[MAX_PATH + 1];
  char newname[MAX_PATH + 1];
  char manifest[MAX_PATH + 1];
  struct stat buffer;
  char *base =0; 
 

  snprintf (manifest, MAX_PATH + 1, "%s%s/%s/%s/%s/%s",
       coursepath, PEOPLE_DIR, sender, ASSIGNMENTS_DIR, dirname, "imsmanifest.xml");
  if( !stat(manifest, &buffer))
       base = get_bb_image_base(manifest);  /* shared_bb_manifest.c */


    /* oldname must be expressed relative to the images/links directory 
     ** thus, the leading ../
    */
  if(base)
  {
     snprintf (oldname, MAX_PATH + 1, "../%s%s/%s/%s/%s/%s/",
            coursepath, PEOPLE_DIR, sender, ASSIGNMENTS_DIR, dirname, base);
     free(base);
  }
  else
   snprintf (oldname, MAX_PATH + 1, "../%s%s/%s/%s/%s", coursepath, PEOPLE_DIR, sender, ASSIGNMENTS_DIR, dirname);

   get_symlink_fname(crs, symlink_fname, user);   /* shared_util.c */
   
  
   /* note next that the path for 'newname' is relative  to the bin directory */
   snprintf (newname, MAX_PATH + 1, "../images/links/%s", symlink_fname);

   remove_stale_symlinks (user->username, crs, access);    /* shared_news_util.c */

   if (symlink (oldname, newname))
      cs_critical_error (ERR_SYMLINK_FAILED, "");
}



