use Test;
use lib $*PROGRAM.parent(2).add("packages/Test-Helpers");
use Test::Util;

plan 21;

# older: L<S16/"Unfiled"/"=item IO.slurp">
# old: L<S32::IO/IO::FileNode/slurp>
# L<S32::IO/Functions/slurp>

{
  dies-ok { slurp "does-not-exist" }, "slurp() on non-existent files fails";
}

{
  dies-ok { slurp "t/" }, "slurp() on directories fails";
  dies-ok { open('t').slurp }, 'slurp on open directory fails';
}

my $test-path = "tempfile-slurp-test";
my $test-contents = "0123456789ABCDEFG風, 薔薇, バズ";
my $empty-path = "tempfile-slurp-empty";

{ # write the temp files
    my $fh = open($test-path, :w);
    $fh.print: $test-contents;
    $fh.close();
    $fh = open($empty-path, :w);
    $fh.print: "";
    $fh.close();
}

ok (my $contents = slurp($test-path)), "test file slurp with path call ok";
isa-ok $contents, Str, "slurp returns a string";
is $contents, $test-contents, "slurp with path loads entire file";
is slurp($empty-path), '', "empty files yield empty string";

{
    my $fh = open $test-path, :r;
    is $fh.slurp, $test-contents, "method form .slurp works";
    $fh.close;
}

{
    is slurp($test-path), $test-contents, "function passed a path works";
}

{
    my $binary-slurp;
    ok ($binary-slurp = slurp $test-path, :bin), ":bin option runs";
    ok $binary-slurp ~~ Buf, ":bin returns a Buf";
    is $binary-slurp, $test-contents.encode, "binary slurp returns correct content";
}

{
    lives-ok { slurp($test-path, :enc('utf8')) }, "slurp :enc - encoding functions";
    is slurp($test-path, :enc('utf8')), $test-contents, "utf8 looks normal";
    #mojibake time
    is slurp($test-path, enc=>'iso-8859-1'),
     "0123456789ABCDEFGé¢¨, èè, ããº", "iso-8859-1 makes mojibake correctly";

}


# slurp in list context

my @slurped_lines = lines(open($test-path));
is +@slurped_lines, 1, "lines() - exactly 1 line in this file";

# slurp in list context on a directory
{
    dies-ok { open('t').lines }, '.lines on a directory fails';
}

unlink $test-path;
unlink $empty-path;
CATCH {
    unlink $test-path;
    unlink $empty-path;
}

subtest '&slurp(IO::Handle)' => {
    plan 9;

    sub f (\c) { make-temp-file content => c }
    is_run 'print slurp', {:0status, :err(''), :out('foobarber')}, :args[
        'foo'.&f.absolute, 'bar'.&f.absolute, 'ber'.&f.absolute,
    ], 'slurp() uses $*ARGFILES';

    is_run '$*ARGFILES.encoding: Nil; say slurp.decode', {
        :0status, :err(''), :out("foobarber\n")
    }, :args[
        'foo'.&f.absolute, 'bar'.&f.absolute, 'ber'.&f.absolute,
    ], 'slurp() uses $*ARGFILES (binary mode)';

    is-deeply slurp('foo'.&f.open), 'foo', 'slurp($fh)';
    # https://github.com/Raku/old-issue-tracker/issues/5283
    #?rakudo.jvm todo 'problem with equivalence of Buf objects'
    is-deeply slurp('foo'.&f.open: :bin), Buf[uint8].new(102,111,111),
        'slurp($fh, :bin)';
    #?rakudo.jvm skip "Unsupported VM encoding 'utf8-c8'"
    is-deeply slurp(buf8.new(200).&f.open: :enc<utf8-c8>),
        buf8.new(200).decode('utf8-c8'), 'slurp($fh, :enc<utf8-c8>)';

    with 'foo'.&f.open {
        is-deeply .&slurp, 'foo', '$fh.&slurp';
        is-deeply .opened, True, 'without :close, handle stays open';
        .close;
    }

    with 'foo'.&f.open {
        is-deeply .&slurp(:close), 'foo', '$fh.&slurp(:close)';
        is-deeply .opened, False, 'with :close, handle is closed';
    }
}

#?rakudo.jvm skip 'floods stderr, IO::Handle.slurp(:bin)'
#?DOES 1
{
  subtest ':bin arg to IO::Handle.slurp method' => {
    plan 5;

    my $content = Buf[uint8].new: "meow\nI ® U".encode;
    my $path = make-temp-file :$content;

    my $fh = $path.open;
    is-deeply $fh.slurp(:bin), $content, 'fresh handle';
    $fh.close;

    $fh = $path.open: :bin;
    is-deeply $fh.slurp(:bin), $content, 'fresh bin handle';
    $fh.close;

    ($fh = $path.open).get;
    is-deeply $fh.slurp(:bin), Buf[uint8].new("I ® U".encode), 'after .get';
    $fh.close;

    my $I-like-big-bufs-and-I-cannot-lie
    = Buf[uint8].new: ("®" x 0x100010).encode;
    $path.spurt: "I ® U\n".encode ~ $I-like-big-bufs-and-I-cannot-lie;
    ($fh = $path.open).get;
    is-deeply $fh.slurp(:bin),
        $I-like-big-bufs-and-I-cannot-lie,
        'after .get on large data file';
    $fh.close;

    $fh = $path.open: :bin;
    $fh.read: 6; # 6 bytes of "I ® U" portion
    is-deeply $fh.slurp(:bin),
        Buf[uint8].new("\n".encode ~ $I-like-big-bufs-and-I-cannot-lie),
        'after .read on large data file with bin handle';
    $fh.close;
  }
}

# https://github.com/rakudo/rakudo/issues/3566
{
    lives-ok { my Buf $b = slurp($?FILE,:bin) },
      'does slurp() with :bin return a Buf-like thing';
    lives-ok { my Buf $b = $?FILE.IO.slurp(:bin) },
      'does .IO.slurp() with :bin return a Buf-like thing';
}

# vim: expandtab shiftwidth=4
