package Onis::Parser;

use strict;
use warnings;

use Exporter;
use Onis::Config qw#get_config#;
use Onis::Data::Core qw#nick_rename store#;
use Onis::Parser::Persistent qw/set_absolute_time get_absolute_time add_relative_time get_state %MONTHNAMES @MONTHNUMS/;

@Onis::Parser::EXPORT_OK = qw/parse last_date/;
@Onis::Parser::ISA = ('Exporter');

our $WORD_LENGTH = 5;

if (get_config ('min_word_length'))
{
	my $tmp = get_config ('min_word_length');
	$tmp =~ s/\D//g;
	$WORD_LENGTH = $tmp if ($tmp);
}

my $VERSION = '$Id: Dircproxy.pm,v 1.5 2004/02/09 15:18:22 octo Exp $';
print STDERR $/, __FILE__, ": $VERSION" if ($::DEBUG);

return (1);

sub parse
{
	my $line = shift;
	my $state;
	
	my $hour = 0;
	my $minute = 0;

	if ($line =~ m/^\* Logging (?:started|finished) \w\w\w,  ?(\d\d?) (\w\w\w) (\d{4}) (\d\d):(\d\d):(\d\d)/)
	{
		if (!defined ($MONTHNAMES{$2})) { return (4); }
		set_absolute_time ($3, $MONTHNAMES{$2}, $1, $4, $5, $6);
	}
	elsif ($line =~ m/^@(\d+)/)
	{
		my $epoch = $1;
		my ($sec, $day, $mon, $year) = (localtime ($epoch))[0, 3, 4, 5];
		($minute, $hour) = (localtime ($epoch))[1, 2];
		
		$year += 1900;
		set_absolute_time ($year, $mon, $day, $hour, $minute, $sec);
	}
	else
	{
		print STDERR $/, __FILE__, ": Not parsed: ``$line'' (no time given)" if ($::DEBUG & 0x20);
		return (2);
	}

	$state = get_state ();
	if ($state != 1)
	{
		return ($state);
	}
	
	if ($line =~ /^@\d+ <([^!]+)!([^>]+)> (.+)/)
	{
		my $data =
		{
			hour	=> $hour,
			minute	=> $minute,
			nick	=> $1,
			host	=> $2,
			text	=> $3,
			type	=> 'TEXT'
		};
		
		my @words = grep { length ($_) >= $WORD_LENGTH } (split (m/\W+/, $3));
		$data->{'words'} = \@words;
		
		store ($data);
	}

	elsif ($line =~ /^@\d+ \[([^!]+)!([^\]]+)\] ACTION (.+)/)
	{
		my $data =
		{
			hour	=> $hour,
			minute	=> $minute,
			nick	=> $1,
			host	=> $2,
			text	=> "* $1 $3",
			type	=> 'ACTION'
		};
		
		my @words = grep { length ($_) >= $WORD_LENGTH } (split (m/\W+/, $3));
		$data->{'words'} = \@words;
		
		store ($data);
	}

	elsif ($line =~ /^@\d+ -\S+- (\S+) \(([^\)]+)\) joined the channel/)
	{
		my $data =
		{
			hour	=> $hour,
			minute	=> $minute,
			nick	=> $1,
			host	=> $2,
			type	=> 'JOIN'
		};
		store ($data);
	}

	elsif ($line =~ /^@\d+ -\S+- (\S+) \(([^\)]+)\) changed mode: ([+-].+)/)
	{
		my $data =
		{
			hour	=> $hour,
			minute	=> $minute,
			nick	=> $1,
			host	=> $2,
			mode	=> $3,
			type	=> 'MODE'
		};
		store ($data);
	}
	
	elsif ($line =~ /^@\d+ -\S+- (\S+) \(([^\)]+)\) changed topic: (.+)/)
	{
		my $data =
		{
			hour	=> $hour,
			minute	=> $minute,
			nick	=> $1,
			host	=> $2,
			text	=> $3,
			type	=> 'TOPIC'
		};
		store ($data);
	}

#	# FIXME
#	elsif ($line =~ /^-\S+- \[(\d\d):(\d\d)\] (\S+) \(([^\)]+)\) quit from IRC: (.*)/ and 0)
#	{
#		my $data =
#		{
#			hour	=> $1,
#			minute	=> $2,
#			nick	=> $3,
#			host	=> $4,
#			text	=> $5,
#			type	=> 'QUIT'
#		};
#		store ($data);
#	}

	elsif ($line =~ /^@\d+ -\S+- (\S+) \(([^\)]+)\) left the channel/)
	{
		my $data =
		{
			hour	=> $hour,
			minute	=> $minute,
			nick	=> $1,
			host	=> $2,
			type	=> 'LEAVE'
		};
		store ($data);
	}

	elsif ($line =~ /^@\d+ -\S+- (\S+) kicked off by (\S+) \(([^\)]+)\): (.+)/)
	{
		my $data =
		{
			hour	=> $hour,
			minute	=> $minute,
			nick_received	=> $1,
			nick	=> $2,
			host	=> $3,
			text	=> $4,
			type	=> 'KICK'
		};
		store ($data);
	}

	else
	{
		print STDERR $/, __FILE__, ": Not parsed: ``$line''" if ($::DEBUG & 0x20);
		return (2);
	}

	return (1);
}

sub last_date
{
	my $time = get_absolute_time ();
	my ($sec, $min, $hour, $day, $month_num, $year) = (localtime ($time))[0 .. 5];
	my $month_name = $MONTHNUMS[$month_num];

	$year += 1900;

	my $retval = sprintf ("* Logging finished xxx, %02u %s %04u %02u:%02u:%02u\n",
		$day, $month_name, $year, $hour, $min, $sec);

	return ($retval);
}
