#!/bin/perl
#
#   Thread_Tag
#   Copyright (C) 2007 Michal Vaner (vorner@ucw.cz)
#
#   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
#   he 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#

$headers = 1;
$hdr = "";
@ids = ();
$mthread = "";
$cleanup = 0;
$filter = 0;
@addflags = @removeflags = ();

sub processHdr {
	if($hdr =~ /^(References|In-Reply-To|Message-ID):/i) {#only the interesting ones
		/<(.*)$/ and push(@ids, $1) foreach(split(/>/, $hdr));#get the IDs
	}
	$hdr = "";
}

sub performCleanup {
	open(IDF, "$ENV{HOME}/.threads_ids") || die "Can not open file to clean";
	open(IDFO, ">$ENV{HOME}/.threads_ids.new") || die "Can not create cleaned file";
	(my $tmp, ($_ !~ /^\s*$/) and (($tmp) = split(/>/, $_)) and $tmp + 3600 * 24 * 30 > time()) and print IDFO $_ while(<IDF>);
	close IDF;
	close IDFO;
	rename("$ENV{HOME}/.threads_ids.new", "$ENV{HOME}/.threads_ids") || die "Could not move file, data loses?!?";
}

sub processTags {
	my($tags) = @_;
	my %tg;
	$tg{$_} = 1 foreach(split(/\s+/, $tags), @addflags);
	delete $tg{$_} foreach(@removeflags);
	$tags = join(' ', keys %tg);
	print "Thread-Tags: $tags\n" if $filter and $tags;
	return $tags;
}

sub finihHeaders {
	$headers = 0;
	&processHdr();
	my %mids, %uthreads;
	$mids{$_} = 1 foreach(@ids);
	$stamp = time();
	if(open(IDF, "$ENV{HOME}/.threads_ids")) {
		while(<IDF>) {
			next if(/^\s*$/);
			my($date, $id, $thread) = split(/[>\n]/, $_);
			if ($date + 3600 * 24 * 33 < $stamp) {#there is 33 days ol message, perform an cleanup
				$cleanup = 1;
			} else {
				$uthreads{$thread} = 1;
			}
			foreach(keys %mids) {
				if($_ eq $id) {
					$mthread = $thread;
					delete $mids{$_};
				}
			}
		}
		close IDF;
	}
	&performCleanup() if($cleanup);
	$uthreads{$mthread = (keys %mids)[0]} = 1 unless($mthread);
	if(each %mids) {
		open(IDF, ">>$ENV{HOME}/.threads_ids") or die "Can not write back";
		print IDF "$stamp>$_>$mthread\n" foreach(keys %mids);
		close IDF;
	}
	open(THO, ">$ENV{HOME}/.threads_tags.new") or die "Can not create tag file";
	my $mtags;
	if(open(THI, "$ENV{HOME}/.threads_tags")) {
		while(<THI>) {
			next if /^\s*$/;
			my($thread, $tags) = split(/[>\n]/, $_);
			if($thread eq $mthread) {
				$mtags = $tags;
			} else {
				print THO $_ if exists $uthreads{$thread};
			}
		}
		close(THI);
	}
	print THO "$mthread>$mtags\n" if $mtags = &processTags($mtags);
	close(THO);
	rename("$ENV{HOME}/.threads_tags.new", "$ENV{HOME}/.threads_tags");
}

sub processLine {
	if($headers) {
		my($ln) = @_;
		if($ln =~ /^\s*$/) {
			&finihHeaders();
		} else {
			if($ln =~ /^\s+/) {
				$hdr = "$hdr $ln";
			} else {
				&processHdr();
				$hdr = $ln;
			}
		}
	}
}

foreach $arg (@ARGV) {
	if($arg eq 'f') {
		$filter = 1;
	} elsif($arg =~ /^-(.*)$/) {
		push(@removeflags, $1);
	} elsif($arg =~ /^\+(.*)$/) {
		push(@addflags, $1);
	}
}

while(<stdin>) {
	chomp;
	&processLine($_);
	print "$_\n" if($filter);
}
