# SPDX-License-Identifier: GPL-2.0-or-later

package Amavis::DbgLog;
use strict;
use re 'taint';

BEGIN {
  use vars qw(@ISA $VERSION);
  $VERSION = '2.412';
}

use POSIX qw(locale_h strftime);
use IO::File ();
use Time::HiRes ();
# use File::Temp ();

use Amavis::Conf qw(:platform $TEMPBASE);
use Amavis::Log qw(write_log);

sub new {
  my $class = $_[0];
  my($self,$fh);
# eval {  # calls croak() if an error occurs
#   $fh = File::Temp->new(DIR => $TEMPBASE, SUFFIX => '.log',
#                         TEMPLATE => sprintf('dbg-%05d-XXXXXXXX',$my_pid));
#   $fh  or warn "Can't create a temporary debug log file: $!";
#   1;
# } or do {
#   my $eval_stat = $@ ne '' ? $@ : "errno=$!";  chomp $eval_stat;
#   warn "Can't create a temporary debug log file: $eval_stat";
# };
  $fh = IO::File->new_tmpfile;
  $fh  or warn "Can't create a temporary debug log file: $!";
  $self = bless { fh => $fh }, $class  if $fh;
  $self;
}

sub DESTROY {
  my $self = $_[0];
  undef $self->{fh};
};

sub flush {
  my $self = $_[0];
  my $fh = $self->{fh};
  !$fh ? 1 : $fh->flush;
}

sub reposition_to_end {
  my $self = $_[0];
  my $fh = $self->{fh};
  !$fh ? 1 : seek($fh,0,2);
}

# Log to a temporary file, to be retrieved later by dump_captured_log()
#
sub write_dbg_log {
  my($self, $level,$errmsg) = @_;
  my $fh = $self->{fh};
  # ignoring failures
  $fh->printf("%06.3f %d %s\n", Time::HiRes::time, $level, $errmsg)  if $fh;
  1;
}

sub dump_captured_log {
  my($self, $dump_log_level,$enable_log_capture_dump) = @_;
  my $fh = $self->{fh};
  if ($fh) {
    # copy the captured temporary log to a real log if requested
    if ($enable_log_capture_dump) {
      $fh->flush or die "Can't flush debug log file: $!";
      $fh->seek(0,0) or die "Can't rewind debug log file: $!";
      my($ln,$any_logged);
      for ($! = 0; defined($ln=<$fh>); $! = 0) {
        chomp($ln);
        my($timestamp,$level,$errmsg) = split(/ /,$ln,3);
        if (!$any_logged) {
          write_log($dump_log_level, 'CAPTURED DEBUG LOG DUMP BEGINS');
          $any_logged = 1;
        }
        write_log($dump_log_level,
                  sprintf('%s:%06.3f %s',
                          strftime('%H:%M', localtime($timestamp)),
                          $timestamp - int($timestamp/60)*60,  $errmsg));
      }
      defined $ln || $! == 0  or die "Error reading from debug log file: $!";
      write_log($dump_log_level, 'CAPTURED DEBUG LOG DUMP ENDS')
        if $any_logged;
    }
    # clear the temporary file, prepare it for re-use
    $fh->seek(0,0) or die "Can't rewind debug log file: $!";
    $fh->truncate(0) or die "Can't truncate debug log file: $!";
  }
  1;
}

1;
