package MailLogParser::Batch;

########## Confixx(R) 3.0 Professional ############
####### Copyright SWsoft, Inc. 2004-2005 ##########
#### http://www.sw-soft.com - info@sw-soft.com ####

# $id: Batch.pm, v 1.0 2003/10/16 $

=head1 NAME

MailLogParser::Batch - пакет сообщений проходящих по smtp-серверу

=head1 SYNOPSIS

  use MailLogParser::Batch;

  $batch = MailLogPaser::Batch->new();

  $batch->addfrom( 'from'       = 'from-box@from-domain.com',
                    'fromLocal' = 1,
                    'size'      = 256);

  $batch->addto( 'to'      => 'to-box@to-domain.com',
                 'toLocal' => '0',
                 'status'  => 'sent' );

  $batch->addto( 'to'      => 'box2@domain2.com',
                 'toLocal' => '0',
                 'status'  => 'sent' );

=head1 DESCRIPTION

Класс для работы с объектами, представляющими собой пакеты сообщений, 
проходящих через smtp-сервер.
Сообщения проходящие через  smtp-сервер могут группироваться. 
Например при использовании листов рассылки,
возврата сообщения отправителю в случае ошибки и т.д.

=over 4

=item new( ... )

Процедура создания нового экземпляра класса
Именованные параметры:
	gid
	type
	ltime
	tag
	firstline
	lastline
	linenumber
	client
	complet


=item gid( [$string] )

индивидуальный идентификатор группы

=item records

ссылка на массив записей MailLogParser::Record

=item type( [sendmail|postfix|qmail] )

тип пакета

=item ltime( [$time] )

локальное время последней записи, относыщеся к данному пакету

=item firstline( [$string] )

шаблон для поиска первой строки log-файла, принадлежащей к пакету

=item lastline( [$string] )

шаблон для поиска последней строки log-файла, принадлежащей к пакету

=item linenumber( [$number] )

номер первой строки log-файла, принадлежащей к пакету

=item client( [$string] )

аттрибут client Применяется для анализа log-файла postfix.

=item complet( [0|1] )

признак завершения пакета. Применяется для анализа log-файла qmail.

=item addfrom( ... )

процедура добавления записи в пакет. 
Проверяет если последняя запись не содержит поля 'from',
то заполняет это поле, не добавляя записи

=item addto( ... )

процедура добавления записи в пакет. 
Проверяет если последняя запись не содержит поля 'to',
то заполняет это поле, не добавляя записи

=item totext

Lвозвращает отладочную информацию об объекте

=back

=head1 SEE ALSO

MailLogParser::Line

=cut

require "MailLogParser/Record.pm"; 

my (%monthNums,$class);

BEGIN {
  use Exporter;
  @ISA = ('Exporter');
  @EXPORT=qw(&gid &records &type &ltime &addfrom &addto &totext &tag
	     &firstline &lastline &linenumber &client &complet &new);

  %monthNums = qw ( 
	Jan  0 Feb  1 Mar  2 Apr  3 May  4 Jun  5
	Jul  6 Aug  7 Sep  8 Oct  9 Mon 10 Dec 11 );

  $class = "MailLogParser::Batch";
}

use strict('vars');


sub new {
  my $class = shift;
  my $self = {};

  bless($self, $class);

  my %args = (
	'gid' => '',
	'type' => '',
	'ltime' => '',
	'tag' => '',
	'firstline' => '',
	'lastline' => '',
	'linenumber' => 0,
	'client' => '',
	'complet' => 0,
	@_
  );

  $self->{_gid}=$args{'gid'};
  $self->{_records}=undef;
  $self->{_type}=$args{'type'};
  $self->{_time}=$args{'ltime'};
  $self->{_tag}=$args{'tag'};
  $self->{_fline}=$args{'firstline'};
  $self->{_lline}=$args{'lastline'};
  $self->{_number}=$args{'linenumber'};
  $self->{_client}=$args{'client'};
  $self->{_complet}=$args{'complet'};


  return $self;
}

sub complet {
  my $self = shift;
  if (@_) {
	$self->{_complet}=shift;
  }
  return $self->{_complet};
}

sub client {
  my $self = shift;
  if (@_) {
	$self->{_client}=shift;
  }
  return $self->{_client};
}

sub firstline {
  my $self = shift;
  if (@_) {
	$self->{_fline}=shift;
  }
  return $self->{_fline};
}
sub lastline {
  my $self = shift;
  if (@_) {
	$self->{_lline}=shift;
  }
  return $self->{_lline};
}

sub linenumber {
  my $self = shift;
  if (@_) {
	$self->{_number}=shift;
  }
  return $self->{_number};
}

sub gid {
  my $self = shift;
  if (@_) {
	$self->{_gid}=shift;
  }
  return $self->{_gid};
}

sub tag {
  my $self = shift;
  if (@_) {
	$self->{_tag}=shift;
  }
  return $self->{_tag};
}

sub records {
  my $self = shift;
#  if (@_) {
#	$self->{_record}=shift;
#  }
  return $self->{_records};
}

sub record {
  my ($self,$index) = @_;
  if ($index && $index>=0 && $index < @{$self->{_records}} ){
	return $self->{_records}[$index];
  }
  else {
	return undef;
  }
}

sub addfrom {
  my $self = shift;
  
  my %args = (
	from => '',
	to => undef,
	size => undef,
	mailer => undef,
	status => undef,
	fromLocal => undef,
	toLocal => undef,
	gid => undef,
	uid => undef,
	@_
  );
  my ($lastRec,$last);
  if (defined $self->{_records}){
	$last=$#{$self->{_records}};
	if ($last>=0) {
	  $lastRec = $self->{_records}->[$last];
	  if ($lastRec->from && $lastRec->size ){
	    undef $lastRec;
	  }
	}
  } 
  	
  if (  defined $lastRec ) {
	$lastRec->from($args{from});
	$lastRec->to($args{to}) if defined $args{to};
	$lastRec->size($args{size}) if defined $args{size};
	$lastRec->mailer($args{mailer}) if defined $args{mailer};
	$lastRec->status($args{status}) if defined $args{status};
	$lastRec->fromLocal($args{fromLocal}) if defined $args{fromLocal};
	$lastRec->toLocal($args{toLocal}) if defined $args{toLocal};
	$lastRec->gid($args{gid}) if defined $args{gid};
	$lastRec->uid($args{uid}) if defined $args{uid};
	
  } else {

    $lastRec=MailLogParser::Record->new( from => $args{from},
	  to => $args{to}, size => $args{size}, mailer => $args{mailer},
	  status => $args{status}, fromLocal => $args{fromLocal}, 
	 toLocal => $args{toLocal}, gid => $args{gid}, uid => $args{uid} );

    push (@{$self->{_records}},$lastRec);

  }	
  return $lastRec;
}

sub addto {
  my $self = shift;
  
  my %args = (
	from => undef,
	to => '',
	size => undef,
	mailer => undef,
	fromLocal => undef,
	toLocal => undef,
	gid => undef,
	uid => undef,
	@_
  );
  my ($lastRec,$last);
  if (defined $self->{_records}){
	$last=$#{$self->{_records}};
	if ( $last >= 0 ){
	  $lastRec = $self->{_records}->[$last];
	  if ( $lastRec->to ){
	    undef $lastRec;
	  }
	}
  } 
  	
  if (  defined $lastRec ) {
	$lastRec->to($args{to});
	$lastRec->from($args{from}) if defined $args{from};
	$lastRec->size($args{size}) if defined $args{size};
	$lastRec->mailer($args{mailer}) if defined $args{mailer};
	$lastRec->status($args{status}) if defined $args{status};
	$lastRec->fromLocal($args{fromLocal}) if defined $args{fromLocal};
	$lastRec->toLocal($args{toLocal}) if defined $args{toLocal};
	$lastRec->gid($args{gid}) if defined $args{gid};
	$lastRec->uid($args{uid}) if defined $args{uid};

  
  } else {

    $lastRec=MailLogParser::Record->new( from => $args{from},
	  to => $args{to}, size => $args{size}, mailer => $args{mailer},
	  status => $args{status}, fromLocal => $args{fromLocal}, 
	 toLocal => $args{toLocal}, gid => $args{gid}, uid => $args{uid} );

    push (@{$self->{_records}},$lastRec);

  }	
  return $lastRec;
}


sub type {
  my $self = shift;
  if (@_) {
	my $line = shift;
	if ($line =~ /\s+?(\S+):\s+/){
	  ($line) = split /\[/,$1;
	  ($line) = split /\//,$line;
	}
	$self->{_type}=$line;
  }
  return $self->{_type};

}

sub ltime {
  my $self = shift;
  if (@_) {
	$self->{_time}=shift;
  }
  return $self->{_time};
}

sub totext {
  my $self = shift;
  my $ret='';
  my ($key,$val,$rec);
  foreach $key (keys %$self){
	$val =$self->{$key};
	if ($key eq '_records' && defined $val){
	  my $i=@$val;
	  $ret.="number of records: $i\n";
	  $i=0;
	  foreach $rec (@$val){
		$i++;
		$ret.="record # $i:\n";
		$ret.= $rec->totext("\t");
		
	  }
	} else {
  	  if (defined ($val)){
	    $ret.="$key\t=\t$val\n";
	  }else{
	    $ret.="$key\t=\tundef\n";
	  }
	}  
  }
  return $ret;
}

return 1;

END {
}


