#!/usr/bin/perl -w
use strict;
use Date::Parse;
use POSIX;
use HTML::Form;
use LWP::UserAgent;
use HTTP::Request;

my $bugzillabase = 'http://ittma-hohah.kibibyte.se/cgi-bin/bugzilla';
my $product = 'HackersDelight';
my $default_component = 'Ingredients';
my $product_version = 'unspecified';
my $platform = 'All';
my $os = 'All';
my $severity = 'enhancement';
my $bugzilla_username = '';
my $bugzilla_password = '';

my $re_firstline = qr/\((\d+)\) +(\d\d)-(...)-(\d{2,4}) +([TSMLGU?](?:\/[SML])?) +(.+)/;
my %work_keywords = (T => 'tinywork', 
		     S => 'smallwork', 
		     M => 'mediumwork',
		     L => 'largework',
		     G => 'giganticwork',
		     U => '',
		     '?' => '');
my @entries;
my %crossrefs;
my $entry;
my $version = 3;
my $lastnumber;

my $createbugs = 0;
my $crossrefbugs = 0;

$createbugs = 1 if ($#ARGV == 0 and $ARGV[0] eq '--create');
$crossrefbugs = 1 if ($#ARGV == 0 and $ARGV[0] eq '--crossref');

sub guess_component ($) {
    my @component_keywords = 
	('ACLs' => qr/acl/i,
	 'Sieve' => qr/sieve/i,
	 'Address Rewriting' => qr/(?:sender|envelope) rewrite|rewrit.*addr/i,
	 'Content Scanning' => qr/scanning/i,
	 'Eximon' => qr/eximon/i,
	 'Filters' => qr/filter(?:s| files)/i,
	 'Logging' => qr/\blog(?:ging| line| more)|\bto log\b/i,
	 'Lookups' => qr/\blookups?\b/i,
	 'Queues' => qr/queue/i,
	 'Routing' => qr/\brout[ei]|certain hosts/i,
	 'SMTP Authentication' => qr/\bPAM\b|authenticator/i,
	 'TLS' => qr/TLS/,
	 'Transports' => qr/transport/i
	 );

    for (my $i = 0; $i < @component_keywords; $i +=2 ){
	if ($_[0] =~ $component_keywords[$i+1]) {
	    return $component_keywords[$i];
	}
    }
}

while (<STDIN>) {
    
    if ($_ =~ $re_firstline) {
	my @tm; 
	my $date;
	$entry = {references => []};
    
	if ($4 > 80) {
	    @tm = strptime("$2 $3 $4");
	}
	else {
	    @tm = strptime("$2 $3 20$4");
	}
	$date = strftime("%Y-%m-%d", 0, 0, 0, @tm[3, 4, 5]);
	$version = 4 if (defined $lastnumber and $1 < $lastnumber);
	$entry->{version} = $version;
	$entry->{number} = $lastnumber = $1;
	$entry->{date} = $date;
	$entry->{work} = $5;
	$entry->{summary} = $6;
	$entry->{component} = guess_component($6);
    }
    elsif (/-{20}/) {
	if (defined $entry->{number}) {
	    while (my ($key, $value) = each %$entry) {
		if (ref $value eq 'ARRAY') {
		    print "$key=[ ";
		    foreach my $ref (@$value) {
			print "$ref ";
		    }
		    print "]\n";
		}
		else {
		    print "$key=$value\n";
		}
	    }
	    push @entries, $entry;
	    $crossrefs{$entry->{version}.'/'.$entry->{number}} = 
		$entry->{references};
	}
	$entry = {};
    }
    elsif (/\S/ or defined $entry->{description}) {
	if (defined $entry->{description}) {
	    $entry->{description} .= "$_";
	}
	else {
	    $entry->{description} = $_;
	}
	while (/(?:see also|and) (?:item )?(?:exim (\d)\/)?(\d+)(?: (?:of|in)(?: the)? exim (\d))?/ig) {
	    push @{$entry->{references}}, 
	         (defined $1 ? $1 
                             : (defined $3 ? $3 : $version)) .'/'.$2;
	}
	$entry->{component} = guess_component($_) unless $entry->{component};
    }
}

my $ua = LWP::UserAgent->new();
$ua->cookie_jar({ file => "$ENV{HOME}/.cookies.txt", autosave => 1 });
my $loginform = HTML::Form->parse($ua->get("$bugzillabase/index.cgi"));
if (defined $loginform->find_input('Bugzilla_login')) {
    $loginform->dump();
    $loginform->value('Bugzilla_login', $bugzilla_username);
    $loginform->value('Bugzilla_password', $bugzilla_password);
    $ua->request($loginform->click);
}

if ($createbugs) {

    my $submitform = HTML::Form->parse($ua->get("$bugzillabase/enter_bug.cgi?product=$product"));

    $submitform->dump();
    $submitform->value('op_sys', $os);
    $submitform->value('rep_platform', $platform);
    $submitform->value('version', $product_version);
    $submitform->value('bug_severity', $severity);
    $submitform->value('bug_file_loc', '');
    
    open OUT, '>processwishlist.bugnumbers';
    
    foreach $entry (@entries) {
	my $key = $entry->{version}.'/'.$entry->{number};
	$submitform->value('short_desc', $entry->{summary});
	$submitform->value('comment', "(This item was imported from the WhishList file, item $key.)\n\n".$entry->{description});
	$submitform->value('keywords', join(' ', @work_keywords{split m'/', $entry->{work}}));
	if ($entry->{component}) {
	    $submitform->value('component', $entry->{component});
	}
	else {
	    $submitform->value('component', $default_component);	
	}
    #$submitform->dump();
	my $result = $ua->request($submitform->click())->as_string();
	if ($result =~ /\<title\>Bug (\d+) Submitted\<\/title\>/s) {
	    print OUT "$key $1\n";
	}
    }
    
    close OUT;
}
elsif ($crossrefbugs) {
     open IN, '<importwishlist.bugnumbers';
     my %bugmap;
     while (<IN>) {
	 chomp;
	 my ($internal_wishnum, $bugzilla_bugnum) = split / /;
	 $bugmap{$internal_wishnum} = $bugzilla_bugnum;
     }
     while (my ($key, $value) = each %crossrefs) {
	 my $id = $bugmap{$key};
	 my $comment = '';
	 print "$key: ";
	 foreach my $crossref (@$value) {
	     print "$crossref ";
	     $comment .= "$crossref = " . ($bugmap{$crossref} ? 
					   "bug ".$bugmap{$crossref} : 
					   "(removed item)")."\n";
	 }
	 print "\n";
	 if ($comment) {
#	 my $key = $entry->{version}.'/'.$entry->{number};
	     my $bugform = HTML::Form->parse($ua->get("$bugzillabase/show_bug.cgi?id=$id"));
	     $bugform->value('comment', $comment);
	     #$bugform->dump();
	     $ua->simple_request($bugform->click());
	 }
     }
}
else {
    print "$0 --create to create the bugs in Bugzilla,\n".
	"$0 --crossref to add crossreferencing comments, using ./importwishlist.bugnumbers\n";
}

