/* 
   The JitterBug bug tracking system
   message matching code

   Copyright (C) Andrew Tridgell 1999

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "jitterbug.h"

extern char *expression;
extern int max_message_size;
extern int casesensitive;
extern int selectid;
extern int messagetype;
extern struct message_info zero_info;

/* get the time on the notes file */
static time_t notes_time(char *name)
{
	struct stat st;
	char buf[100];

	if (!valid_id(name)) return 0;
	
	sprintf(buf,"%s.notes", name);
	if (stat(buf, &st)) return 0;
	return st.st_mtime;
}

/* see if a file matches the expresion */
static int search_file(char *name)
{
	char *r;
	char *expr = expression;
	int ret=0;

	if (lp_search_program()) {
		return external_search(name, expression);
	}

	r = load_file(name,NULL,max_message_size);
	if (!r) return 0;

	if (!casesensitive) {
		strlower(r);
		expr = strdup(expression);
		strlower(expr);
	}

	if (exp_match(r, expr)) ret = 1;
	free(r);
	if (expr != expression) free(expr);

	return ret;
}



/* see if a message matches the a expresion. If it does then fill in
   the info structure */
static int search_message(char *name)
{
	char buf[100];
	int i;

	if (search_file(name))
		return 1;

	sprintf(buf,"%s.notes", name);

	if (search_file(buf))
		return 1;

	for (i=1;i<MAX_REPLIES;i++) {
		sprintf(buf,"%s.reply.%d", name, i);
		if (!file_exists(buf, NULL)) break;

		if (search_file(buf))
			return 1;
	}

	for (i=1;i<MAX_REPLIES;i++) {
		sprintf(buf,"%s.followup.%d", name, i);
		if (!file_exists(buf, NULL)) break;

		if (search_file(buf))
			return 1;
	}

	return 0;
}


/* see if a message matches the current search criterion. If it does
   then fill in the info structure */
int match_message(char *name, struct message_info *info)
{
	if (!valid_id(name)) return 0;

	if (selectid) {
		return (atoi(name) == selectid);
	}

	if (messagetype == MTYPE_PENDING) {
		time_t t1, t2, t3;
		count_followups(name, &t1);
		count_replies(name, &t2);
		t3 = notes_time(name);
		if (t1 <= t2 || t1 <= t3) return 0;
	}

	if (messagetype == MTYPE_REPLIED) {
		if (count_replies(name, NULL) == 0) return 0;
	}

	if (messagetype == MTYPE_UNREPLIED) {
		if (count_replies(name, NULL)) return 0;
	}

	if (!pulldown_match(name)) return 0;

	if (!*expression) return 1;

	if (search_message(name)) {
		if (!get_info(name, info, max_message_size)) return 0;
		
		return 1;
	}

	return 0;
}


/* count the messages in a directory that match the specified 
   regular expression */
int count_messages(void)
{
	int i, count=0;
	char **list;

	list = load_dir_list(".",valid_id);
	if (!list) return 0;

	for (i=0;list[i];i++) {
		struct message_info info = zero_info;
		if (match_message(list[i],&info))
			count++;
		free_info(&info);
	}

	free_list(list);

	return count;
}

