#include <stdio.h>
#include <sys/stat.h>		/* for stat() */
#include <time.h>
#include <string.h>
#include <ctype.h>

#include "global.h"
#include "custom.h"		/* for date FORMAT strings */

#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_read_infofile.h"
#include "manhat-lib/shared_lock.h"




static void
read_parameters (char *course, char *key, long *offset, char *from_prog)
{

  char off_set[MAX_FILENAME + 1];


  cs_get_required_parameter ("crs", course, MAX_PATH);
  cs_get_required_parameter ("id", key, MAX_KEY);
  cs_get_required_parameter ("loc", off_set, MAX_FILENAME);
  cs_get_required_parameter ("from", from_prog, MAX_PATH);

  *offset = atol (off_set);
}




/* reads the outbox file and then the corresponding *.inf file, to get everything
   ** ready to be displayed
   * */
static void
process_outbox_record (long offset, OUTBOX_RECORD * outbox,
		       INFO * infofile_info, CONFIG_STRUCT *conf, SESSION *user)
{
  char outbox_path[MAX_PATH + 1];
  FILE *fp;

  snprintf (outbox_path, MAX_PATH + 1, "%s%s/%s/%s/%s",
	    conf->course_path, PEOPLE_DIR, user->username, MAIL_DIR, OUTBOX_FNAME);
  fp = fopen (outbox_path, "r");
  if (!fp)
    cs_critical_error (ERR_FOPEN_READ_FAILED, "");
    
  get_shared_lock(fileno(fp),1);    /* shared_lock.c */  
  if (fseek (fp, offset, SEEK_SET))
    cs_critical_error (ERR_FSEEK_FAILED, "");
  if (fread (outbox, sizeof (OUTBOX_RECORD), 1, fp) != 1)
    cs_critical_error (ERR_FREAD_FAILED, "");
  release_lock(fileno(fp));  
  fclose (fp);

  read_post_infofile (user->username, outbox->info_fname, infofile_info, conf);  /* shared_read_infofile.c */

}



static void
set_recipient_info (OUTBOX_RECORD * outbox, INFO * infofile_info)
{
  #define MAX_TMP_NAME 30
  PERSON_NODE *pptr;
  int i =0;
  char name[MAX_TMP_NAME];
  char timestring[MAX_TIMESTRING + 1], timestring1[MAX_TIMESTRING + 1];
  char *escaped_subject = (char *) 0;
  
  if(cgi_html_escape_strfunc(outbox->subject,&escaped_subject) == STATUS_OK)
      {
	cs_set_value("subject", escaped_subject);
	if(escaped_subject)
	    free(escaped_subject);
      }
  else
        cs_set_value("subject", outbox->subject);


  strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT,
	    localtime (&outbox->time_sent));

  cs_set_value("sent_time", timestring);

/******** To: list ********/
  for ( pptr = person_head; pptr; pptr = pptr->next)
  {
    if (pptr->data.how_received == TO)
      {
	/* prepare time read */
	if (pptr->data.time_read)
	{
	  snprintf(name, MAX_TMP_NAME, "to.%d.time_read", i);
	  strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT,
		    localtime (&pptr->data.time_read));
	  cs_set_value(name, timestring);
	}

	/* prepare time deleted
	** the test for 'VERSION24' is to maintain backward compatability
	** after major changes to Post Office in version 2.4 -
	** search for VERSION24 in global.h for more info.
	*/
	if ( (infofile_info->version == VERSION24) && pptr->data.time_deleted)
	{
	  strftime (timestring1, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT,
		    localtime (&pptr->data.time_deleted));
	  snprintf(name, MAX_TMP_NAME, "to.%d.time_deleted", i);
	  cs_set_value(name, timestring1);
	}
        snprintf(name, MAX_TMP_NAME, "to.%d.realname", i);
        cs_set_value(name, pptr->data.realname);
        i++;
      }
    }

/******** CC: list ********/
  i =0;
  for ( pptr = person_head; pptr; pptr = pptr->next)
  {
    if (pptr->data.how_received == CC)
      {
	/* prepare time read */
	if (pptr->data.time_read)
	{
	  snprintf(name, MAX_TMP_NAME, "cc.%d.time_read", i);
	  strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT,
		    localtime (&pptr->data.time_read));
	  cs_set_value(name, timestring);
	}

	/* prepare time deleted */
	if ((infofile_info->version == VERSION24) && pptr->data.time_deleted)
	{
	  strftime (timestring1, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT,
		    localtime (&pptr->data.time_deleted));
	  snprintf(name, MAX_TMP_NAME, "cc.%d.time_deleted", i);
	  cs_set_value(name, timestring1);
	}
        snprintf(name, MAX_TMP_NAME, "cc.%d.realname", i);
        cs_set_value(name, pptr->data.realname);
        i++;
    }
    
  }



/******** BCC: list ********/
  i =0;
  for ( pptr = person_head; pptr; pptr = pptr->next)
  {
    if (pptr->data.how_received == BCC)
      {
	/* prepare time read */
	if (pptr->data.time_read)
	{
	  snprintf(name, MAX_TMP_NAME, "bcc.%d.time_read", i);
	  strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT,
		    localtime (&pptr->data.time_read));
	  cs_set_value(name, timestring);
	}

	/* prepare time deleted */
	if ((infofile_info->version == VERSION24) && pptr->data.time_deleted)
	{
	  strftime (timestring1, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT,
		    localtime (&pptr->data.time_deleted));
	  snprintf(name, MAX_TMP_NAME, "bcc.%d.time_deleted", i);
	  cs_set_value(name, timestring1);
	}
        snprintf(name, MAX_TMP_NAME, "bcc.%d.realname", i);
        cs_set_value(name, pptr->data.realname);
        i++;
    }
    
  }

  #undef MAX_TMP_NAME 
}


static void
set_attachment_info (INFO * infofile_info, CONFIG_STRUCT *conf, SESSION *user)
{
  #define MAX_TMP_NAME 30
  ATTACHMENT_NODE *aptr;
  struct stat buf;
  char mail_dir[MAX_PATH + 1];
  char file_path[MAX_PATH + 1];
  char name[MAX_TMP_NAME];
  char temp[MAX_TMP_NAME];
  int i =0;

  if (infofile_info->no_attachments == -1)
     cs_set_int_value("website_attached", 1);
  else if (attachment_head)
    {
      cs_set_int_value("attachment_count", infofile_info->no_attachments );
      snprintf (mail_dir, MAX_PATH + 1, "%s%s/%s/%s/", conf->course_path, PEOPLE_DIR,
		user->username, MAIL_DIR);
      for (i = 0, aptr = attachment_head; aptr; aptr = aptr->next, i++)
	{
	  snprintf (file_path, MAX_PATH + 1, "%s%s", mail_dir,
		    aptr->data.unique_fname);
	  stat (file_path, &buf);
	  snprintf(name, MAX_TMP_NAME, "attachment.%d.filename", i);
	  cs_set_value(name, aptr->data.orig_fname);
	  snprintf(name, MAX_TMP_NAME, "attachment.%d.size", i);
	  snprintf(temp, MAX_TMP_NAME, "%ld", (long)buf.st_size);
	  cs_set_value(name, temp);
	}
    }
  #undef MAX_TMP_NAME 
}







static void
set_outbox_info (char *course, char *key, long offset, char *from,
                     CONFIG_STRUCT *conf, SESSION *user)
{
  OUTBOX_RECORD outbox;
  INFO infofile_info;

  cs_set_course_info(conf);
  cs_set_current_time();
  
  process_outbox_record (offset, &outbox, &infofile_info, conf, user);
  set_recipient_info (&outbox, &infofile_info);
  set_attachment_info (&infofile_info, conf, user);
  cs_set_int_value("is_outbox", 1);
}





int
main (void)
{
  char course[MAX_PATH + 1];	/* from crs=? command line */
  char key[MAX_KEY + 1];	/* from id=? command line */
  long offset;			/* from loc=? command line */
  char from_prog[MAX_PATH + 1];	/* from from=? command line */
  SESSION user;
  CONFIG_STRUCT conf;		/* the configuration read from config file */

  cs_cgi_init();

  read_parameters (course, key, &offset, from_prog);
  read_configuration_file (course, &conf);	/* shared_util.c */
  validate_key (key, &user, &conf);	/* shared_util.c */

  set_outbox_info (course, key, offset, from_prog, &conf, &user);

  free_person_list ();      /* shared_read_infofile.c */
  free_attachment_list ();  /* shared_read_infofile.c */

  /** NOTE: same cs file is used for both inbox and outbox info **/
  cs_cgi_display("post_inbox_outbox_info", 1);
  cs_cgi_destroy();
  return 0;

}




