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

#include "global.h"
#include "custom.h"

#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_person_list.h"
#include "manhat-lib/shared_read_infofile.h"
#include "manhat-lib/shared_translate_url.h"
#include "manhat-lib/shared_access.h"
#include "manhat-lib/shared_lock.h"
#include "manhat-lib/shared_news_util.h"
#include "manhat-lib/shared_spelling_util.h"






static void
read_parameters (char *course,	/* from cmd line */
		 char *key,	/* from cmd line */
		 char *from_prog,	/* from cmd line */
		 long *offset,	/* from cmd line */
		 int *from_inbox	/* from src= */
  )
{

  char temp_string[25];

  cs_get_required_parameter ("crs", course, MAX_PATH);
  cs_get_required_parameter ("id", key, MAX_KEY);
  cs_get_required_parameter ("from", from_prog, MAX_FROM);

  cs_get_required_parameter ("loc", temp_string, 24);
  *offset = atol (temp_string);

  cs_get_required_parameter ("src", temp_string, 24);
  *from_inbox = atoi (temp_string);



}




static void
set_basic_data (char *course, char *key, char *from, CONFIG_STRUCT *conf)
{

  char temp[MAX_PATH + 1];

  cs_set_value("crs", course);
  cs_set_value("id", key);
  cs_set_value("from", from);

  cs_set_course_info(conf);
  cs_set_current_time();
  cs_set_int_value("is_forward", 1);


/*** now put in back button *****/

  translate_url_substitutes (temp, from, MAX_PATH + 1, 1);	/*shared_translate_url.c */
  cs_set_value("back_url", temp);


  cs_set_int_value("msg.subject.max", MAX_SUBJECT - 1);
  cs_set_int_value("msg.subject.size", MAX_SUBJECT - 1);
  cs_set_int_value("msg.textarea.hard_wrap", USE_TEXTAREA_HARD_WRAP); 
}









static void
process_inbox (long offset, INBOX_RECORD * inbox, INFO * infofile_info,
               CONFIG_STRUCT *conf, SESSION *user)
{
  char inbox_path[MAX_PATH + 1];
  FILE *fp;

  snprintf (inbox_path, MAX_PATH + 1, "%s%s/%s/%s/%s", conf->course_path, PEOPLE_DIR,
	    user->username, MAIL_DIR, INBOX_FNAME);
  fp = fopen (inbox_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 (inbox, sizeof (INBOX_RECORD), 1, fp) != 1)
    cs_critical_error (ERR_FREAD_FAILED, "");

  release_lock(fileno(fp));    /* shared_lock.c */
  fclose (fp);

/*** now read the info file fcn is in shared_read_infofile.c */
  read_post_infofile (inbox->newfile_info.sender,
		      inbox->newfile_info.info_fname, infofile_info, conf);



}



static void
process_outbox (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");

  get_shared_lock(fileno(fp), 1);
  
  if (!fp)
    cs_critical_error (ERR_FOPEN_READ_FAILED, "");
  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));   /* shared_lock.c */  
  fclose (fp);

/*** now read the info file fcn is is shared_read_infofile.c  */
  read_post_infofile (user->username, outbox->info_fname, infofile_info, conf);

}



static void
do_forward_textarea (const char *sender_username, const char *msg_fname, CONFIG_STRUCT *conf )
{
  FILE *fp;
  char fullpath[MAX_PATH + 1];
  struct stat file_stat;
  int longest;
  char *buf =0, *add_reply_mark =0;


  snprintf (fullpath, MAX_PATH + 1, "%s/%s/%s/%s/%s", conf->course_path, PEOPLE_DIR,
	    sender_username, MAIL_DIR, msg_fname);
  if(stat(fullpath, &file_stat))
      cs_critical_error (ERR_STAT_FAILED, fullpath);

  buf = (char *) malloc( (file_stat.st_size +1) * sizeof(char) );
  if(!buf)
        cs_critical_error (ERR_MALLOC_FAILED, "");

  fp = fopen (fullpath, "r");
  if (!fp)
    cs_critical_error (ERR_FOPEN_READ_FAILED, fullpath);
    
  get_shared_lock(fileno(fp),1);    /* shared_lock.c */
  fread(buf, file_stat.st_size, 1, fp);

   *(buf + file_stat.st_size ) = '\0';
  release_lock(fileno(fp));   /* shared_lock.c */  
  fclose (fp);

  longest = find_longest_line(buf,conf);    /* shared_news_util.c */
  cs_set_int_value("msg.textarea.cols", longest + 1);

  longest = find_num_lines(buf);                      /* shared_news_util.c */
  add_reply_mark = add_mark_to_msg(buf, longest);     /* shared_news_util.c */
  
  cs_set_value("msg.textarea.body", add_reply_mark);
  if(buf)
       free(buf);
  if(add_reply_mark)
       free(add_reply_mark);

}






static void
set_fwd_form (char *course, char *key, char *from_prog,
		  long offset, int from_inbox, CONFIG_STRUCT *conf, SESSION *user)
{
  INBOX_RECORD inbox;
  OUTBOX_RECORD outbox;
  INFO infofile_info;
  char *fwd_subject = 0;

  char sender[MAX_USERNAME + 1];
  char temp[MAX_USERNAME + 1];
  char subject[MAX_SUBJECT + 1];
  char realname[MAX_NAME + 1];
  char info_fname[MAX_PATH + 1];
  int attach, i;
  P_NODE *p;
  ATTACHMENT_NODE *aptr;

  set_basic_data (course, key, from_prog, conf);  
  insert_spell_check_button(conf);

  if (from_inbox)
    {
      process_inbox (offset, &inbox, &infofile_info, conf, user);
      strncpy (subject, inbox.newfile_info.subject, MAX_SUBJECT + 1);
      strncpy (sender, inbox.newfile_info.sender, MAX_USERNAME + 1);
      strncpy (realname, inbox.newfile_info.sender_realname, MAX_NAME + 1);
      attach = (infofile_info.no_attachments ==	 -1) ? 0 : infofile_info.no_attachments;
      strncpy (info_fname, inbox.newfile_info.info_fname, MAX_FILENAME + 1);
    }
  else
    {
      process_outbox (offset, &outbox, &infofile_info, conf, user);
      strncpy (subject, outbox.subject, MAX_SUBJECT + 1);
      strncpy (sender, user->username, MAX_USERNAME + 1);
      strncpy (realname, user->realname, MAX_NAME + 1);
      attach =	(infofile_info.no_attachments == -1) ? 0 : infofile_info.no_attachments;
      strncpy (info_fname, outbox.info_fname, MAX_FILENAME + 1);
    }


  
  p = build_option_person_list (conf);  /* shared_person_list.c */
  
  if(!ALLOW_POST_OFFICE_MSGS_TO_SELF)                    /* #defined in custom.h */
        p = option_list_remove_user(p, user->username);  /* shared_person_list.c */
  set_option_userlist (p);
  
  /* set subject but must replace quotes " with &quot; */
  fwd_subject = replace_quot(subject);         /* shared_news_util.c */
  if(fwd_subject)
   {
    cs_set_value("msg.subject.value", fwd_subject);    
    free(fwd_subject);
   } 

  
  /* handle textarea */

  do_forward_textarea (sender, infofile_info.msg_fname, conf);
  cs_set_value("msg.textarea.author", realname);
  
  free_option_person_list (p);


  if (attach)			/* if there were files attached to the original msg */
    {
      cs_set_value("sender", sender);	
      cs_set_value("inf", info_fname);	

      cs_set_int_value("files", attach);
      cs_set_int_value("has_attach", 1);

      for (aptr = attachment_head, i = 0; aptr; aptr = aptr->next, i++)
      {
          snprintf(temp, MAX_USERNAME +1, "attach.file.%d.value", i);
	  cs_set_value(temp, aptr->data.unique_fname);
          snprintf(temp, MAX_USERNAME +1, "attach.file.%d.orig", i);
	  cs_set_value(temp, aptr->data.orig_fname);
      }
  }
 

  cs_set_int_value("attach.max_files", 	conf->mail_attachments);


}


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

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

  if(!has_write_permission(&user, &conf))   /* shared_access.c */
      access_denied_error();                /* shared_access.c */

  set_fwd_form (course, key, from_prog, offset, from_inbox, &conf, &user);
  cs_cgi_display("post_new_memo", 1);
  cs_cgi_destroy();
  return 0;
}





