#!perl

# number of tests is variable here. using no_plan, as this works on both SLE11_SP2 and 12.1
use Test::More qw(no_plan);
use FindBin;
BEGIN { unshift @INC, "$1/../blib/lib" if $FindBin::Bin =~ m{(.*)} };
use File::Unpack2;
use File::Temp;
use JSON;

# plan tests => 5;

my $testdir = File::Temp::tempdir("FU_06_XXXXX", TMPDIR => 1, CLEANUP => 1);

my $u = File::Unpack2->new(destdir => $testdir, verbose => 0, logfile => "$testdir/log");
$u->exclude(vcs => 1, add => ['data']);
$u->unpack("t");
ok(-f "$testdir/log", "have $testdir/log after unpacking");
open IN, "<", "$testdir/log";
my $log = JSON::from_json(join '', <IN>);
close IN;
ok(ref($log) eq 'HASH', "logfile is valid JSON");
ok(!exists($log->{unpacked}{'/'}), "Dummy not file seen");
ok(length($log->{end}), "end timstamp file seen");

my $log_scalar;
my $testdir2 = File::Temp::tempdir("FU_06_XXXXX", TMPDIR => 1, CLEANUP => 1);
$u = File::Unpack2->new(destdir => $testdir2, verbose => 0, logfile => \$log_scalar);
$u->exclude(vcs => 1, add => ['data']);
$u->unpack("t");
my $log2 = JSON::from_json($log_scalar);
ok(ref($log2) eq 'HASH', "scalar log is valid JSON");

my $filecount = 0;
for my $f (keys %{$log2->{unpacked}})
  {
    ok($log2->{unpacked}{$f}{mime} =~ m{^text/}, "$f: $log2->{unpacked}{$f}{mime} matches text/*");
    $filecount++
  }
ok($filecount > 10, "more than 10 unpacked files: $filecount");

# Regression (happy path): a completed unpack must leave recursion_level back at 0. A leak here
# is what previously tripped $RECURSION_LIMIT on large trees and silently aborted deep recursion.
is($u->{recursion_level} || 0, 0, "recursion_level returns to 0 after a successful unpack");

# Regression: when an inner unpack() call finds $archive missing on disk
# (the path can vanish between the caller's stat and us re-stating it under
# concurrent file-system activity), the early return must not leave
# $self->{recursion_level} incremented. If it does, the outer call's
# --recursion_level == 0 check never fires and the JSON epilog is never
# written, producing an invalid log file.
{
  my $testdir3 = File::Temp::tempdir("FU_06_XXXXX", TMPDIR => 1, CLEANUP => 1);
  my $u3 = File::Unpack2->new(destdir => $testdir3, verbose => 0, logfile => "$testdir3/log");
  my $level_before = $u3->{recursion_level} || 0;
  $u3->{recursion_level} = 1;        # pretend we're already inside an unpack
  $u3->unpack("/this/path/does/not/exist.tar.gz");
  is($u3->{recursion_level}, 1, "recursion_level preserved when inner unpack() hits non-existent path");
}

# Regression: recursion beyond the emergency $RECURSION_LIMIT must stop gracefully (return, no crash
# or runaway) - the backstop against quines / absurdly deep nesting.
{
  my $testdir = File::Temp::tempdir("FU_06_XXXXX", TMPDIR => 1, CLEANUP => 1);
  my $u4 = File::Unpack2->new(destdir => $testdir, verbose => 0, logfile => '/dev/null');
  $u4->{recursion_level} = 1000;    # pretend we are absurdly deep
  my $rc = eval { local $SIG{ALRM} = sub { die "ALARM\n" }; alarm 20; my $r = $u4->unpack("t/data"); alarm 0; $r };
  alarm 0;
  ok(defined $rc, "unpack() past the recursion limit returns instead of recursing/hanging");
}

# done_testing does not exist in SLE11_SP2
# done_testing();
