#!/usr/bin/env perl

# Regression test for updateTarget()'s missing-transport-datasets-directory crash, found running
# the real harness against dd-nas1 (Documentation/TESTING.md Step 3.3, target role, after the
# source side had never populated the transport datasets folder in that run).
#
# ZFS_Utils::getDirectoryList documents "Returns: ARRAYREF of full-path filenames on success, 0 on
# error" - a bare scalar 0, not an empty arrayref, when opendir() fails (e.g. the directory doesn't
# exist yet). Every other caller in sneakernet guards against that (copyCleanupScripts,
# removeObsoleteScripts both check `$files && @$files`/`ref` before dereferencing), but
# updateTarget() fed the raw result straight into processTransportFiles()'s
# `foreach my $filename (@$files)`, dying with `Can't use string ("0") as an ARRAY ref` under
# `strict refs` instead of correctly treating "no dataset directory yet" the same as "nothing to
# import" - a real, reachable condition any time the target runs before the source side has ever
# written anything to the transport (a fresh install, or the transport folder was just emptied).
#
# sneakernet is a script, not a requireable module (unguarded top-level logic runs on load), so
# the fix is copied here verbatim, per this project's "extract a sub/block into a stub harness"
# testing convention (see test_destroyedSourceDataset.pl).

use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/..";
use ZFS_Utils qw(getDirectoryList);
use File::Temp qw(tempdir);

my $passed = 0;
my $failed = 0;

sub ok {
   my ($cond, $desc) = @_;
   if ($cond) { print "  PASS: $desc\n"; $passed++; }
   else       { print "  FAIL: $desc\n"; $failed++; }
}

# --- verbatim copy of updateTarget's dataset-dir listing + guard, sneakernet (post-fix) ---
sub getTransportFilesOrEmpty {
   my ($datasetDir) = @_;
   my $files = getDirectoryList( $datasetDir, '\.IV$', 1 );
   $files = [] unless ref($files) eq 'ARRAY';
   return $files;
}
# --- end copy ---

{
   my $sandbox = tempdir( CLEANUP => 1 );
   my $files = getTransportFilesOrEmpty( "$sandbox/does-not-exist" );
   ok( ref($files) eq 'ARRAY', "a nonexistent dataset directory yields an ARRAYREF, not the bare scalar 0" );
   ok( scalar(@$files) == 0, "...and it's empty, correctly treated as 'nothing to import'" );
   # This is the exact statement that used to crash under strict refs when $files was "0".
   my @seen;
   eval { push @seen, $_ for @$files; 1 } or ok(0, "dereferencing the guarded result does not crash: $@");
   ok( scalar(@seen) == 0, "iterating the guarded result is a no-op, as processTransportFiles expects" );
}

{
   my $sandbox = tempdir( CLEANUP => 1 );
   open my $fh, '>', "$sandbox/ds1" or die $!;
   close $fh;
   my $files = getTransportFilesOrEmpty( $sandbox );
   ok( ref($files) eq 'ARRAY' && scalar(@$files) == 1, "an existing populated directory still returns its real file list unaffected" );
}

print "\n" . "=" x 70 . "\n";
print "Test Summary: $passed passed, $failed failed\n";
print "=" x 70 . "\n";

exit( $failed == 0 ? 0 : 1 );
