#! /usr/bin/perl -w

# SVN Bot
# Copyright (C) 2004-2005 Clément Stenac
	   
# 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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.

use Email::Simple;
use Net::IRC;
use threads;

use Net::HTTP;
$| = 1;

my $chan = "#videolan";;
my $folder="/home/zorglub/Maildir/svn/new/"; # Don't forget trailing /

my $irc = new Net::IRC;

my $saved = 0;

my $connexion = $irc->newconn( Nick => "vlcsvnbot", Server => "zen.via.ecp.fr", Port =>30000, SSL => 1 );

$connexion->add_handler('public', \&on_public);                # local

$connexion->join($chan);

$thread = threads->new( \&global_thread, $connexion );
$thread->detach();

#$thread2 = threads->new( \&warn_thread, $connexion );
#$thread2->detach();

$irc->start();

sub global_thread
{ 
   my $connexion = shift;
   my $i = 0;
   while( 1 != 2 ) 
   {
   	$i++;
	if( $i % 10 == 1 )
	{
  	   check_paste( $connexion );
	}
	   if( opendir DIR, $folder )
	   {
		@files = readdir( DIR );
		foreach $file ( @files )
		{
			$file ne "." or next;
			$file ne ".." or next;
			print "NEW MAIL -$file-\n";
			parse_mail( $connexion, $file );
			unlink $folder.$file;
		}
		closedir DIR;
   	}
	sleep 1;
   }
}


sub parse_mail
{
	my $connexion = shift;
	my $mail_file = shift;
	open MAIL, $folder.$mail_file ;
	my $mail_text = join '',<MAIL>;
	close MAIL;

	my $mail = Email::Simple->new( $mail_text );
	print "SUBJECT IS ".$mail->header( "Subject" )."\n";
	print "FROM IS ".$mail->header( "From" )."\n";

	if( $mail->header( "From" ) =~ /svn\@videolan\.org/  )
	{
	    my @elems = split / / , $mail->header( "Subject" );
	    # ML without [ML] header
	    if( $elems[0] =~ /libdvdcss\:/ ||
	    	$elems[0] =~ /pkg-multimedia\:/ )
	    {
	    	$elems[0] =~ s/://;
		$elems[3] =~ s/r//;
		$elems[4] =~ s/\(//;
		$elems[4] =~ s/\)//;
		
	    	$connexion->privmsg( $chan , $elems[0]." commit by ".$elems[4]. " rev ".$elems[3] );
	    }
	    else
	    {
                for( $elems[5] ) { s/^\(//; s/\)$//; }
	        $elems[4] =~ s/r//;
  	        $elems[1] =~ s/://;

	        $connexion->privmsg( $chan , $elems[1]." commit by ".$elems[5]. " rev ".$elems[4] );
	    }

	    @body_lines = split /\n/, $mail->body;
	    my $ok = 0;
	    foreach $current ( @body_lines )
	    {
		if( $ok == 1 )
		{
			$connexion->privmsg( $chan, $current );
			last;
		}
		if( $current =~ /^$/ ) {  $ok = 1; }
	    }
	}
	elsif( $mail->header( "From" ) =~ /nightlies\@videolan\.org/ )
	{
	    $connexion->privmsg( $chan, $mail->header("Subject") );
	}
}


# Warn about broken SVN
sub warn_thread
{
   my %status;
   @svns = ('x264', 'vlc', 'vls', 'libdvdcss', 'libdvbpsi', 'libdvdplay' );
   foreach $svn ( @svns ) { $status{$svn} = 0; }
   my $connexion = shift;
   while( 1 != 2 ) 
   {
        print "Checking SVN : ";
   	foreach $svn ( @svns )
	{
	    print $svn." ";
   	    my $ret = system "svn ls svn://svn.videolan.org/$svn/ > /dev/null";
	    if( $ret != 0 ) 
	    {
	    	if( $status{$svn} == 0 )
		{
    		    $connexion->privmsg( $chan, "$svn SVN failure !" );
		}
		$status{$svn} = 1;
	    }
	    else
	    {
		if( $status{$svn} == 1 )
		{
		    $connexion->privmsg( $chan, "$svn SVN ok");
		}
		$status{$svn} = 0;
	    }
	}
	print "\n";
	sleep 60;
   }
}




sub on_public
{
    my ($connexion, $event ) = @_;
    my($arg) = $event->args;
    my $from = $event->from;
    $from =~ s/([A-z0-9_\-]*)!.*/$1/;
    print "<".$from."> ".$arg."\n";
    if( $arg =~ /^\@milestone\ (.*)$/ )
    {
	$answer= get_milestone( $1 );
	print "Getting milestone $1 -> answer is $answer\n";
	$connexion->privmsg( $chan, $answer);
    }
}

sub check_paste
{
    my $connexion = shift;
    #Net::HTTP does shit
    my $out = `wget -o /dev/null -O /dev/stdout paste.videolan.org/query.php`;
    @lines = split( '\n', $out );
    $last = $lines[2];

    if( $last != $saved && $saved != 0 )
    {
	$connexion->privmsg( $chan, $lines[0]." pasted '".$lines[1].
			 "' (http://paste.videolan.org/".$last.")");
    }
    $saved = $last;
}


sub get_milestone
{

my $milestone = shift;

my $server = Net::HTTP->new(Host => "trac.videolan.org" ) || die;
$server->write_request( GET => "/vlc/query?status=new&status=assigned&status=reopened&milestone=".$milestone, "User-Agent" => "svnbot" );

my ($code, $mess, %h)  = $server->read_response_headers;

my $out = "";
while (1 )
{
    my $buf;
    my $n = $server->read_entity_body( $buf, 1024 );
    last unless $n;
    $out = $out.$buf;
}

my %owners;
my %severities;
my %statuss;

@lines = split( '\n', $out );
my $in_ticket = 0;
my $current_td = 0;
my ($priority, $component, $owner, $status);
foreach $line (@lines)
{
#    print "*** reading $line\n";
    if( $line =~ /<td class="ticket">/ )
    {
	if( $in_ticket == 1 )
	{
	    trim( \$priority );
	    trim( \$owner );
	    trim( \$component );
	    trim( \$status );
	    $priorities{$priority}++;
	    $owners{$owner}++;
	    $statuss{$status}++;
            $total_bugs++;
	    $current_td = 0;
	}
	$in_ticket = 1;
    }
    if( $in_ticket == 1 )
    {
	if( $line =~ /<td>$/ )
	{
	    $current_td++;
	    $in_td = 1;
	    next;
	}
	if( $line =~ /<\/td>$/ ) 
        {
 	    $in_td = 0;
	    next;
        }
	if( $in_td == 1 )
	{
#	    print "Captured interesting line $line - current td $current_td\n" ;
	    if( $current_td == 2 )
		{$status = $line;}
	    if( $current_td == 3 )
		{$component = $line;}
	    if( $current_td == 4 )
		{$owner = $line;}
	    if( $current_td == 5 )
		{$priority = $line;}
	}
    }
}
if( $in_ticket == 1 )
{
    trim( \$priority );
    trim( \$owner );
    trim( \$component );
    trim( \$status );
    $priorities{$priority}++;
    $owners{$owner}++;
    $statuss{$status}++;
    $total_bugs++;
    $current_td = 0;
}

$answer = "Milestone ".$milestone.": $total_bugs tickets (";
while( ($key,$value) = each %priorities )
{
   $answer .= "$value $key, ";
}
chop $answer;
chop $answer;
$answer .=")";
return $answer;
}
 
sub trim
{
   $s=shift;
   $$s =~ s/^\s+//;$$s=~ s/\s+$//;
}
