package tsk::logger;
use strict; 
use IO::File;
use threads; 
use threads::shared; 

sub new ($$)
{
  my ($class, $logFile, $errorFile ) = @_; 
  my @log_q : shared;
  my @err_q : shared; 
  my $stopLogger : shared = 0; 
  
  my $self = {
  	_logFile => $logFile,,
  	_errFile => $errorFile,
  	_logQueue => \@log_q,
  	_errQueue => \@err_q, 
  	_stop => \$stopLogger
  };
  
  return bless $self, $class;  
}

sub log
{
	my ($this, $msg) = @_; 
	my $q = $this->{'_logQueue'};  
	lock(@$q); 
	push (@$q, $msg) and cond_signal(@$q); 
}

sub error
{
	my ($this, $msg) = @_; 
	my $q = $this->{'_errQueue'};  
	lock(@$q); 
	push (@$q, $msg) and cond_signal(@$q); 
}

sub start()
{
	my ($this) = @_;
	
	sub __logger
	{
		my ($this) = @_; 
		my $logFile = $this->{'_logFile'};
		open(LFILE, '>'.$logFile) or die("Error: Failed to open log file: $logFile");
		my $queue = $this->{'_logQueue'}; 
		my $sref = $this->{'_stop'};
		while ( $$sref == 0 || @$queue > 0 )
		{
			lock(@$queue); 
			cond_wait @$queue
				until(@$queue || $$sref); 
			#print $file shift @$queue, "\n"; 
			my $msg = shift @$queue; 
			print LFILE $msg, "\n";
			#print $msg, "\n"; 
		}	
		close(LFILE);
	}
	
	sub __error
	{
		my ($this) = @_; 
		my $errFile = $this->{'_errFile'};
		open(EFILE, '>'.$errFile) or die("Error: Failed to open log file: $errFile");
		my $queue = $this->{'_errQueue'}; 
		my $sref = $this->{'_stop'};
		while ( $$sref == 0 || @$queue > 0 )
		{
			lock(@$queue); 
			cond_wait @$queue
				until(@$queue || $$sref); 
			my $msg = shift @$queue; 
			print EFILE $msg, "\n";
			#print $msg, "\n";  
		}	
		close(EFILE);
	}

	my $tid = threads->create( \&__logger, $this );
	unless ( defined($tid) )
	{
		die("Error: Failed to start logger theread");
	}
	
	$tid = threads->create( \&__error, $this );
	unless ( defined($tid) )
	{
		die("Error: Failed to start error logger theread");
	}
	return 1; 
}

sub stop()
{
	my ($this) = @_ ;
	my $qlog   = $this->{'_logQueue'};
	my $qerr   = $this->{'_errQueue'};
	lock(@$qlog);
	lock(@$qerr);
	${$this->{'_stop'}} = 1;
	cond_broadcast(@$qlog);
	cond_broadcast(@$qerr);
}

1; 
