# flexraw's read/write tests, copied from fastraw's tests.
# There are still many tests to write; see the notes at the bottom
# of this document.

use PDL::LiteF;
# PDL::Core::set_debugging(1);
kill INT,$$  if $ENV{UNDER_DEBUGGER}; # Useful for debugging.

use strict;
use warnings;

use Test::More;
use Test::PDL;
use File::Temp qw(tempdir);
use File::Spec::Functions;
use PDL::IO::FlexRaw;

$PDL::debug = 0;

# Get a temporary directory and file name, which obviously we'll need for testing
# saving and reading of data.
my $tmpdir = tempdir( CLEANUP=>1 );
my $name = catfile($tmpdir, "tmp0");

# Set up the working filename and make sure we're working with a clean slate:

my $x = pdl [2,3],[4,5],[6,7];
my $header = writeflex($name, $x);
ok((-f $name), "writeflex should create a file");

my $header_bis = [ { %{$header->[0]}, Dims => [2, undef] } ];
eval { readflex($name, [@$header_bis, @$header_bis]) };
like $@, qr/>1 header/, 'readflex only allows undef dim when only one hash';
is_pdl readflex($name, $header_bis), $x, "read back with undef highest dim correct";

writeflexhdr($name, $header);
ok(-f "$name.hdr", "writeflexhdr should create a header file");

is_pdl readflex($name), $x, "A ndarray and its saved copy should be about equal";

my ($c1, $c2) = ([0,0,0,0],[0,0,0,0]);
my $c = pdl [$c1,$c2];
my $d = pdl [1,1,1];
my $cdname = $name . 'cd';
$header = writeflex($cdname, $c, $d);
ok -f $cdname, "writeflex saves 2 pdls to a file";
writeflexhdr($cdname, $header);
ok -f "$cdname.hdr", "writeflexhdr create a header file";
# This is sf.net bug #3375837 "_read_flexhdr state machine fails"
my @cd = do { no warnings; readflex($cdname) };
is 0+@cd, 2, 'sf.net bug 3375837';
is_pdl $cd[0], $c, 'sf.net bug 3375837';
is_pdl $cd[1], $d, 'sf.net bug 3375837';
# Clean up for another test
unlink $cdname, $cdname . '.hdr';	# just to be absolutely sure

{
my $gname = $name.'g';
local $PDL::IO::FlexRaw::writeflexhdr = 1;
writeflex($gname, $d, $c); # 2D last so can append
my @dc = readflex($gname);
is_pdl $dc[0], $d;
is_pdl $dc[1], $c;
my $e = pdl(2,2,2,2);
glueflex($gname, $e);
@dc = readflex($gname);
is_pdl $dc[0], $d;
is_pdl $dc[1], pdl($c1,$c2,$e);
}

{
my $cplx = pdl '1+2i 3+4i 5+6i';
my $cname = catfile($tmpdir, "cplx");
my $hdr = writeflex($cname, $cplx);
is_deeply $hdr, [{ BadFlag => 0, BadValue => undef,
  Dims => [ 3 ], NDims => 1, Type => 'cdouble'
}], 'header correct';
is_pdl readflex($cname, $hdr), $cplx, 'reads back right';
}

# some mapflex tests
SKIP: {

   my $c = eval { mapflex($name) };
   if ($@) {
      diag("$@");
      if ($@ =~ m/mmap not supported/) {
         skip('no mmap support', 5);
      }
   }

   is_pdl $c, $x, "An ndarray and its mapflex representation should be about equal";

   $c += 1;
   undef $c;
   my $y = readflex($name);
   is_pdl $x+1, $y, "Modifications to mapfraw should be saved to disk no later than when the ndarray ceases to exist";

   # We're starting a new test, so we'll remove the files we've created so far
   # and clean up the memory, just to be super-safe
   unlink $name, $name . '.hdr';
   undef $x;
   undef $y;

   # First create and modify the ndarray
   $header = [{NDims => 2, Dims => [3,2], Type => 'float'}];
   # Fix this specification.
   $x = mapflex($name, $header, {Creat => 1});
   writeflexhdr($name, $header);
   ok(defined($x), 'mapflex create ndarray');

   skip('no mapflex ndarray to check', 2) unless defined $x;
   $x += xvals $x;
   $x += 0.1 * yvals $x;
   # save the contents
   undef $x;
   # Load it back up and see if the values are what we expect
   $y = readflex($name);
   is_pdl $y, float([[0,1,2],[0.1,1.1,2.1]]),
      "mapfraw should be able to create new ndarrays";

   undef $x; undef $y; # cleanup
   # test for bug mentioned in https://perlmonks.org/?node_id=387256
   my $p1 = sequence(5);
   my $header1 = writeflex($cdname, $p1);
   writeflexhdr($cdname, $header1);
   my $p2 = sequence(5) + 8;
   my $header2 = writeflex($name, $p2);
   writeflexhdr($name, $header2);
   $p1 = mapflex($cdname);
   is $p1.'', '[0 1 2 3 4]', 'right value before second mapflex';
   $p2 = mapflex($name);
   is $p1.'', '[0 1 2 3 4]', 'still right value after second mapflex';
   is $p2.'', '[8 9 10 11 12]', 'second ndarray values right';
   undef $p1; undef $p2;
   unlink $cdname, $cdname . '.hdr';
}

# Clean things up a bit
unlink $name, $name . '.hdr';

# Test the file header options:

# Tests to write still:
# Test using file handles instead of file names
# test read_flexhdr
# test gzip stuff

done_testing;
