/* Somewhat BSD dependant (uses opendir, etc.) */

/* Included in foldMHP.h
 #include <sys/types.h>
 #include <sys/dir.h>
*/
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>

#include "memory.h"
#include "foldMHP.h"
#include "registry.h"
#include "msg.h"
#include "bool.h"

/* This should do The Right Thing (hint: this isn't it).  MH has some
 * real way of doing this */

extern char *getenv(const char *);

#define CVT_FOLDER_TO_FILE(foldername, buffer) do {strcpy(buffer, getenv("HOME"));strcat(buffer,"/Mail/");strcat(buffer,foldername);} while(0)

AlFoldMH AlFoldMH_create(folder_name, generic_folder)
     const char *folder_name;
     AlFolder generic_folder;
{
  char buf[1000];
  AlFoldMH_rep *temp;
  DIR *temp_dirp;

  assert(strlen(folder_name)>0 && strlen(folder_name)<255);
  CVT_FOLDER_TO_FILE(folder_name,&buf[0]);
  temp_dirp = opendir(&buf[0]);
  if (temp_dirp == NULL) 
    return NULL;
  temp = create();
  temp->file_name = Memory_allocate(strlen(&buf[0])+1);
  strcpy((char *)temp->file_name, &buf[0]);
  temp->dirp = temp_dirp;
  temp->initial_telldir_value = telldir(temp_dirp);
  temp->generic_folder = generic_folder;
  temp->iter_count = 0;
  return raise(temp);
}

NORET AlFoldMH_destroy(mh_folder)
     AlFoldMH mh_folder;
{
  AlFoldMH_rep *temp = lower(mh_folder);

  assert(temp->iter_count == 0);
  closedir(temp->dirp);
  Memory_free((VOIDP)temp->file_name);
  destroy(temp);
}

AlFoldMHIter AlFoldMH_iter_create(mh_folder, recurse)
     AlFoldMH mh_folder;
     Bool recurse;		/* recurse not implemented */
{
  AlFoldMH_rep *temp = lower(mh_folder);
  AlFoldMHIter_rep *new_iter = create_iter();

  assert(mh_folder != NULL);
  new_iter->the_folder = temp;
  new_iter->telldir_value = temp->initial_telldir_value;
  new_iter->prev_context = NULL;
  new_iter->cur_msg = NULL;
  new_iter->cur_buf = NULL;
  ++temp->iter_count;
  return raise_iter(new_iter);
}

static NORET clear_cur_iter(temp_iter)
     AlFoldMHIter_rep *temp_iter;
{
  if (temp_iter->cur_msg != NULL) {
    AlMsg_destroy(temp_iter->cur_msg);
    temp_iter->cur_msg = NULL;
  }
  if (temp_iter->cur_buf != NULL) {
    Memory_free((VOIDP)temp_iter->cur_buf);
    temp_iter->cur_buf = NULL;
  }
}

NORET AlFoldMH_iter_destroy(iter)
     AlFoldMHIter iter;
{
  AlFoldMHIter_rep *temp_iter = lower_iter(iter);

  clear_cur_iter(temp_iter);
  --(temp_iter->the_folder->iter_count);
  destroy_iter(temp_iter);
}

static NORET try_to_parse(const char *, AlFolder, Msg *, char **);

/* tests whether a name refers to a legal MH message.  MH messages are
 * numbers only */

static Bool is_message(name)
     const char *name;
{     
  const char *p;

  for (p = name; *p != NULL; ++p)
    if (!isdigit(*p))
      return Bool_FALSE;
  return Bool_TRUE;
}

Msg AlFoldMH_iter_get(iter)
     AlFoldMHIter iter;
{
  AlFoldMHIter_rep *temp_iter = lower_iter(iter);
  struct direct *directp;
  DIR *dirp = temp_iter->the_folder->dirp;
  static char namebuf[MAXNAMLEN+1];
  static char pathbuf[1000];

  if (telldir(dirp) != temp_iter->telldir_value)
    seekdir(dirp, temp_iter->telldir_value);
  directp = readdir(dirp);
  temp_iter->telldir_value = telldir(dirp);
  while (directp != NULL) {
    strncpy(&namebuf[0], &directp->d_name[0], (int)directp->d_namlen);
    namebuf[(int)directp->d_namlen] = '\0';
    if (is_message(&namebuf[0]) == Bool_TRUE) {
      strcpy(&pathbuf[0], temp_iter->the_folder->file_name);
      strcat(&pathbuf[0], "/");
      strcat(&pathbuf[0], &namebuf[0]);
      clear_cur_iter(temp_iter);
      try_to_parse(&pathbuf[0], 
		   temp_iter->the_folder->generic_folder,
		   &(temp_iter->cur_msg),
		   &(temp_iter->cur_buf));
      if (temp_iter->cur_msg != NULL)
	return temp_iter->cur_msg;
    }  
    directp = readdir(dirp);
    temp_iter->telldir_value = telldir(dirp);
  } 
  return NULL;
}


NORET try_to_parse(name, folder, cur_msgp, cur_bufp)
     const char *name;
     AlFolder folder;
     Msg *cur_msgp;
     char **cur_bufp;
{
  FILE *f;
  char *bufp;
  int cur_pos, buf_len, ch;
  Msg temp_msg;
  Registry folder_specific_reg = Registry_create(0, 0); /* foo */

  if ((f = fopen(name, "r")) != NULL) {
    buf_len = BUFSIZ;
    cur_pos = 0;
    bufp = (char *)Memory_allocate(buf_len);
    for (;;) {
      ch = getc(f);
      if (cur_pos >= buf_len) {
	buf_len = buf_len + BUFSIZ;
	bufp = (char *)Memory_reallocate((VOIDP)bufp, buf_len);
      }	
      if (ch == EOF) {
	*(bufp + cur_pos++) = (char)'\0';
	break;
      } else
	*(bufp + cur_pos++) = (char)ch;
    }
    fclose(f);
    temp_msg = AlMsg_create(bufp, "", "", folder_specific_reg, folder);


/* start debug 
    putchar('\n');
    puts(bufp);
    temp_msg = NULL;
* end debug */

    if (temp_msg == NULL)
      Memory_free((VOIDP)bufp);
    else {
      *cur_msgp = temp_msg;
      *cur_bufp = bufp;
    }
  }
}
