#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>

#include "globals.h"
#include "mbox.h"

int count( struct mbox_struct * mb ) {
	FILE * f = 0;
	/* Usually the e-mails are wrapped at most at column 79
	 * This length will speed things up */
	char line[81] = "";
	int ctotal = 0;
	int cnew = 0;
	int status_line;

	if ( (f = fopen(mb->file, "r")) == NULL ) {
		return(-1);
	}

	while ( fgets(line, 80, f) ) {
		if (!strncmp(line, "From ", 5)) {
			++ctotal;
			++cnew;
			status_line = 0;
		} else if ( ! status_line ) {
			if ( !strncmp(line, "Status: ", 8) ) {
				status_line = 1;
				if (mb->flags & FLAG_UNREAD_AS_NEW) {
					if (!strncmp(line, "Status: RO", 10))
						--cnew;
				} else if (!strncmp(line, "Status: R", 9)) {
					--cnew;
				}
			}
		}
		while ( !strchr(line, '\n') && fgets(line, 80, f) ) {
		}
	}
	fclose(f);

	if ( (mb->cnew != cnew) && (cnew != 0) ) {
		pthread_mutex_lock(&mb->mutex);
		mb->flags |= FLAG_ARRIVED;
		pthread_mutex_unlock(&mb->mutex);
	}
	mb->ctotal = ctotal;
	mb->cnew = cnew;

	return(0);
}

void mbox_handle( struct mbox_struct * mb ) {
	struct stat stat_buf;
	/* Since we never really intend to quit this function,
	 * all "global" stuff may go on the stack here */
	time_t mod_time = 0;
	off_t last_size = 0;

	if ( ! strlen(mb->file) ) {
		printf("asmail: mbox_handle: no mailbox file specified.\n");
		mb->status = STAT_FAIL;
		signal_update();
		pthread_exit(NULL);
	}
	while (1) {
		mb->status |= STAT_RUN;
		signal_update();
		if ( stat(mb->file, &stat_buf) ) {
			/* Yes, we have to keep trying. The mailbox
			 * may be on a filesystem that experiences
			 * problems, like NFS. */
			printf("asmail: mbox_handle: stat (%s) failed.\n",
					mb->file);
			mb->status = STAT_FAIL;
			signal_update();
		} else {
			/* It seems that mod_time is not quite a reliable
			 * source of file modification check. Let's try
			 * to use other sources of information too. */
			if ( ( stat_buf.st_ctime != mod_time ) ||
			     ( stat_buf.st_size != last_size ) ) {
				mod_time = stat_buf.st_ctime;
				last_size = stat_buf.st_size;
				if (count(mb)) {
					mb->status = STAT_FAIL;
					signal_update();
				} else {
					mb->status = STAT_IDLE;
					if ( mb->cnew > 0)
						mb->mail = MAIL_NEW;
					else if ( mb->ctotal > 0 )
						mb->mail = MAIL_OLD;
					else
						mb->mail = MAIL_NONE;
					signal_update();
				}
			} else {
				mb->status = STAT_IDLE;
				signal_update();
			}
		}
		sleep_check(mb->update);
	}
}

