#!/usr/bin/perl

# Format of data files is as follows:
# line 1: target value names each separated by a space
# line 2: # of total words for all documents in each target value each
#         separated by a space
# line 3: number of documents for each category
# line 4: a vocab word, followed by pairs of category numbers and the word
#         frequency for that category

# When a vocab word is refiled it is assumed that this is the desired
#      target value (or folder, in this case).

# tv = target value

# This program is written in an attempt to emulate the MH refile command
#   while adding the benefit of allowing it to learn user preference with
#   a bayesian-style learning algorithm.  
# The only options which it currently emulates are '-src +folder' and '-file
#   file'.  It supports refiling multiple messages, but does not support
#   filing messages into multiple folders.  It also does not support
#   subfolders.

open(TMP, ">> /tmp/irefile.info");

print TMP "irefile called ";
print TMP "(0-$#ARGV)\n";

print "tmp opened\n";

$home_dir = $ENV{"HOME"}."/";

print "Home dir = $home_dir\n";

open(MH, "< $home_dir.mh_profile") || die "No .mh_profile found";

while (<MH>) {
    if (m/Path: (\w+)/) {
	$mail_path = $1;
	$mail_path .= "/";
    }
    if (m/draft-folder: (\w+)/) {
	$draft_folder = $1;
    }
}

print "Mail Path = $mail_path\n";


# gets command line arguments - prints them to temporary file

$i = 0;
while ($i <= $#ARGV) {

# for ($i=0; $i <= $#ARGV; $i++) {

    print TMP $ARGV[$i]." ";

    if ($ARGV[$i] =~ m/\-src/) {
	if ($ARGV[$i+1] =~ m/^\+(\S+)/) {
	    $source_folder = $1;
	    print TMP "source folder = $source_folder\n";
	    $i++;
	} else {
	    print "Error: folder name lacks preceeding '+' or is";
	    print " in wrong format.\n";
	    &print_usage;
	}
    } elsif ($ARGV[$i] =~ m/\-file/) {
	$source_file = $ARGV[$i+1];
	print TMP "source file = $source_file\n";
	$i++;
    } elsif ($ARGV[$i] =~ m/^\+([^+]+)/) {
	$dest_folder = $1;
	print TMP "destination folder = $dest_folder\n";
    } else {
	$orig_message[$#orig_message+1] = $ARGV[$i];
	print TMP "message name = $ARGV[$i]\n";
    }
    $i++;
}   

$tot_words = 0;

# target values and 'n' both start with index 1
$tv[0] = 0;

$data_file = $home_dir.".idata";

if (open(DATA, "< $data_file")) 
{
    # reads in category names
    $line = <DATA>;
    while ($line =~ s/(\w+)\s+//) 
    {
	$tv[$#tv+1] = $1;
    }

    # reads in total number of words for each category
    $line = <DATA>;
    $i = 1;
    while ($line =~ s/(\d+)\s+//) 
    {
	print TMP "$tv[$i] = $1\n";
	$n{$tv[$i++]} = $1;
    }
    if ($i <= $#tv) { ouch("Bad data file format - line #2"); }

    # reads in number of documents for each category
    $line = <DATA>;
    $i = 1;
    while ($line =~ s/(\d+)\s+//)
    {
	$docs{$tv[$i++]} = $1;
	$tot_docs += $1;
    }
    if ($i <= $#tv) { ouch("Bad data file format - line #3"); }

    # reads in actual word frequencies
    $word[0] = "";

    while (($line = <DATA>) && (!($line =~ m/^\s*$/)))  {
	$tot_words++;

	# reads word
	$line =~ s/^(\w+)\s+// || ouch("Couldn't read vocab word");
	$word[$#word+1] = $1;
	$index{$1} = $#word;
	
	# reads age of word
	$line =~ s/^(\d+)\s+// || ouch("Couldn't read age of word");
	$age{$word[$#word]} = $1;

	# reads in frequency per category   cat_num:freq
	while ($line =~ s/(\d+):(\d+)\s+//) 
	{
	    $nk{$word[$#word].",".$tv[$1]} = $2;
	    $sum_nk{$word[$#word]} += $2;
	}
	
	if (!($line =~ m/^\s*$/)) { ouch("Vocab line # $tot_words has bad format"); }
    }
}

close(DATA);

print "Done with data\n";

foreach $msg (@orig_message) {
    if ($source_folder ne "") {
	print "Opening $home_dir$mail_path${source_folder}/$msg\n";
	open(MSG, "< " . $home_dir . $mail_path . $source_folder."/".$msg) ||
	    print TMP "Could not open " . $home_dir . $mail_path . $source_folder."/".$msg . "\n";
    } else {
	print "Opening $msg\n";
	open(MSG, "< $msg") || print TMP "Could not open $msg\n";
    }

    @lines = <MSG>;

    &rcvstore($dest_folder);

    print "Input file: \n";

    foreach $line (@lines) 
    {
	while ($line =~ s/([A-Za-z]+)[^A-Za-z]+//) 
	{
	    $wrd = $1;
            # get rid of tiny words
	    if (length($wrd) > 2) 
	    {
		$wrd =~ tr/A-Z/a-z/;
		print $wrd." ";
	 	if ($index{$wrd} == 0) 
		{
		    $word[$#word+1] = $wrd;
		    $index{$wrd} = $#word;
		    $nk{$wrd.",".$dest_folder}++;
		} else {
		    $nk{$wrd.",".$dest_folder}++;
		}
		$n{$dest_folder}++;
	    }
	}
    }
    close(MSG);

    $docs{$dest_folder}++;

}

&remove_msgs;

# reopen the data file and write the learned information

print "Home dir = $home_dir\n";
print "Mail path = $mail_path\n";

open(DATA, "> $home_dir.idata") || die "Couldn't open data file\n";

open(FOLDERS, "< $home_dir${mail_path}.folders") || die "Couldn't find .folders\n";

# prints category names to data file (uses .folders file to determine folders)
$i = 1;
while (<FOLDERS>) {
    chop;
    $tv[$i++] = $_;
    print DATA $_." ";
}

close(FOLDER);

print DATA "\n";

# prints total word frequency values
for ($i=1; $i <= $#tv; $i++) 
{
    if ($n{$tv[$i]} > 0) {
	print DATA $n{$tv[$i]}." ";
    } else {
	print DATA "0 ";
    }
}
print DATA "\n";

# prints number of documents for each category
for ($i=1; $i <= $#tv; $i++) 
{
    if ($n{$tv[$i]} > 0) {
	print DATA $docs{$tv[$i]}." ";
    } else {
	print DATA "0 ";
    }
}
print DATA "\n";

for ($i=1; $i <= $#word; $i++) 
{
    $age{$word[$i]}++;

    # if the word is infrequent, discard it (don't print it to DATA)
    if (($age{$word[$i]} < 12) || ($sum_nk{$word[$i]} > 3))
    {
	print DATA $word[$i]." ".$age{$word[$i]}." ";

	for ($j=1; $j <= $#tv; $j++) {
	    if ($nk{$word[$i].",".$tv[$j]} > 0) {
		print DATA $j.":".$nk{$word[$i].",".$tv[$j]}." ";
	    }
	}
	print DATA "\n";
    }
}

close(DATA);

print TMP "\n";
close(TMP);

exit 0;

# rcvstore function expects lines of input file to be stored in @lines - bad
#   assumption, I know.  I'll fix it later.  Really :)

sub rcvstore {
    local($mailbox) = @_;

    print TMP "Filed to $mailbox\n";
    
    open(RCV, "| /usr/lib/mh/rcvstore +$mailbox") || die "could not rcvstore\n";
    
    foreach $line (@lines) {
	print RCV $line;
    }
    
    close(RCV);
}

sub remove_msgs {
    
    print TMP "Removing old messages\n";
    
    $string = "";
    foreach $msg (@orig_message) {
	$string .= $msg." ";
    }
    if ($source_folder ne "") { $string .= "+$source_folder"; }
    $string = "/usr/bin/mh/rmm ".$string;
    system $string;
    print "\nCurrent dir = $PWD\n";
    open(ECHO, "echo \$PWD |");
    print <ECHO>;
    print TMP $string."\n";
}
