package RotatingLog;

use FileHandle;

sub new
{
    my ($this, $file, $maxlog, $logno) = @_;
    my  $class = ref($this) || $this;
    my  $self = {};

    bless($self, $class);
    $self->{"file"} = $file;
    ($maxlog=1024*1024) unless( $maxlog );
    ($logno=7) unless( $logno );
    $self->{"maxlog"} = $maxlog;
    $self->{"logno"} = $logno;
    $self->{"pending"} = undef;
    $self->{"pending_timeout"} = 30;
    $self->{"mintime"} = 30 * 60;
    $self->{"nexttime"} = time + ($self->{"mintime"});
    return $self;
}


sub set_rotate_hook {
    my( $self, $callback ) = @_;

    $self->{"rotatehook"} = $callback;
}


sub log {
    my( $self, $text ) = @_;

    if( $self->{"pending"} ) {
	my $pending = $self->{"pending"};
	push( @{$pending->{"buffer"}}, $text ) if( $text );
	if( Platform::replace( $self->{"file"}, ($self->{"file"}).".0" ) ) {
	    delete $self->{"pending"};
	}
	elsif( $pending->{"time"} < time - $self->{"pending_timeout"} ) {
	    BigSister::common::log( "warning", "log rotate timed out" ); 
	    delete $self->{"pending"};
	}
	else {
	    return;
	}
	my $line;
	foreach $line (@{$pending->{"buffer"}}) {
	    $self->log( $line );
	}
	return;
    }

    unless( $self->{"fh"} ) {
	print "RotatingLog: attaching to log file ".($self->{"file"})."\n" if( $BigSister::common::dl>4 );
	$self->{"fh"} = new FileHandle;
	unless( open( $self->{"fh"}, ">>".($self->{"file"}) ) ) {
	    BigSister::common::log( "warning", "cannot append to log file ".($self->{"file"}) ) unless( $self->{"warned"} );
	    $self->{"warned"} = 1;
	    undef $self->{"fh"};
	    return;
	}
	select $self->{"fh"};
	$| = 1;
	select STDOUT;
	$self->{"cnt"} = 5;
	$self->{"nexttime"} = time + $self->{"mintime"};
    }
    return unless( defined $text );
    $self->{"warned"} = 0;
    my $fh = $self->{"fh"};
    print $fh (time)." ".$text."\n";
    return if( $self->{"cnt"}-- );
    $self->{"cnt"} = 50;
    if( ((-s $self->{"file"}) > $self->{"maxlog"}) && ($self->{"nexttime"} < time) ) {

	if( $self->{"rotatehook"} ) {
	    &{$self->{"rotatehook"}}( $self->{"fh"}, $self->{"file"} );
	}

	close $self->{"fh"};
	delete $self->{"fh"};
	print "rotating status logs\n" if( $BigSister::common::dl>5 );
	if( -f ($self->{"file"}).".0" ) {
	    my $i;
	    for( $i=$self->{"logno"}; $i; $i-- ) {
		Platform::replace( ($self->{"file"}).".".($i-1), ($self->{"file"}).".".$i );
	    }
	}
	unless( Platform::replace( $self->{"file"}, ($self->{"file"}).".0" ) ) {
	    $self->{"pending"} = { "time" => time, "buffer" => [] };
	}
	$self->log();
    }
}

1;
