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

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

#include "manhat-lib/shared_mime_type.h"
#include "manhat-lib/shared_read_infofile.h"
#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_news_util.h"
#include "manhat-lib/shared_podcast_util.h"
#include "manhat-lib/shared_access.h"




static void
read_parameters (char *course,  char *sender,char *fname, char *inf, char *podcast_key)
{
  cs_get_required_parameter ("crs", course, MAX_FILENAME);	/* shared_cgi_util.c */
  cs_get_required_parameter ("fname", fname, MAX_FILENAME);
  cs_get_required_parameter ("sender", sender, MAX_USERNAME);
  cs_get_required_parameter ("inf", inf, MAX_FILENAME);
  cs_get_required_parameter ("id", podcast_key, MAX_KEY);
}



static void
get_original_fname (char *original_fname, const char *fname)
{
  ATTACHMENT_NODE *ptr;

  for (ptr = attachment_head; ptr; ptr = ptr->next)
    if (!strcmp (ptr->data.unique_fname, fname))
      {
	strncpy (original_fname, ptr->data.orig_fname, MAX_FILENAME + 1);
	return;
      }
  cs_critical_error (ERR_UNABLE_TO_DETERMINE_FILENAME, "");
}





static void
deliver_file (char *mime_type, char *source_file, char *dest_file)
{
#define CHUNKSIZE 8192  

  FILE *fp;

  struct stat buf;
  int bytes_read;
  int bytes_left;
  char buffer[CHUNKSIZE];

  if (stat (source_file, &buf))
    cs_critical_error (ERR_STAT_FAILED, source_file);

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


  printf ("Content-type:%s\n", mime_type);
  printf ("Content-disposition: filename=\"%s\"\n", dest_file);
  printf ("Content-length: %ld\n\n", (long)buf.st_size);

  bytes_left = buf.st_size;
  bytes_read = CHUNKSIZE;
  while (bytes_left)
    {
      if (bytes_left < CHUNKSIZE)
	bytes_read = bytes_left;
      if (fread (buffer, bytes_read, 1, fp) != 1)
	cs_critical_error (ERR_FREAD_FAILED, source_file);
      bytes_left -= bytes_read;
      if (fwrite (buffer, bytes_read, 1, stdout) != 1)
	cs_critical_error (ERR_FWRITE_FAILED, "stdout");
    }
  fclose (fp);

#undef CHUNKSIZE
}






static void
send_podcast_file (char *sender, char *fname,
		    char *info_fname, char *course, CONFIG_STRUCT *conf)
{
  NEWS_INFO infofile_info;
  char original_fname[MAX_FILENAME + 1];
  char mime_type[MAX_MIME_TYPE + 1];
  char source_path[MAX_PATH + 1];
  int is_realaudio;   /* needed for call to get_mime_type() but not used */


  read_news_infofile (sender, info_fname, &infofile_info, PODCASTS, conf);	/* shared_read_infofile.c */

  get_original_fname (original_fname, fname);
  set_discussion_names (conf->course_path, sender, PODCASTS);			/* shared_news_util.c */
  snprintf (source_path, MAX_PATH + 1, "%s/%s", discussion_path, fname);	/* discussion_path global in shared_news_util.c */

  get_mime_type (source_path, original_fname, mime_type, &is_realaudio);        /* shared_mime_type.c */
  deliver_file (mime_type, source_path, original_fname);
}

/** This program does no authentication, yet we need a SESSION user
*** This function sets up a 'dummy' user as a student.
**/
static void
get_dummy_student_user(SESSION *user)
{
 strncpy(user->username, "_unknown_", MAX_USERNAME + 1 );
 strncpy(user->realname, "_unknown_", MAX_NAME + 1);
 strncpy(user->id,"_unknown_id_", MAX_ID + 1);
 strncpy(user->alias, "_unknown_", MAX_NAME + 1);
 user->team = '!';
 user->group = STUDENT;
 user->expires = 0;
}



int
main (void)
{
  char course[MAX_PATH + 1];		/* from crs=? command line */
  char sender[MAX_USERNAME + 1];	/* from user=? command line */
  char fname[MAX_FILENAME + 1];	   	/* from fname=? cmd line */
  char info_fname[MAX_FILENAME + 1];	/* from inf=? cmd line */
  char podcast_key[MAX_KEY + 1];        /* from key=? cmd line */
  SESSION user;
  CONFIG_STRUCT conf;			/* the configuration read from config file */

  cs_cgi_init();
  read_parameters (course,  sender, fname, info_fname, podcast_key);

  read_configuration_file (course, &conf);	/* shared_util.c */
  validate_podcast_key(podcast_key, &conf);     /* shared_podcast_util.c */

  /* since we're not really authenticating, fill in some dummy values for 
  ** a student that can safely be used throughout this program
  */
  get_dummy_student_user(&user);

  has_write_permission(&user, &conf);   /* shared_access.c - access is denied if user can't view this course */


  send_podcast_file (sender, fname, info_fname, course, &conf);
  log_podcast_download(info_fname, &conf);    /* shared_podcast_util.c */  
  
  free_attachment_list ();	/* shared_read_infofile.c */
  cs_cgi_destroy();
  return 0;

}

