package TestCase::Lib::SPVM::IO::File {
  use SPVM::IO::File;
  use SPVM::StringList;
  use SPVM::Util (chomp_lf, equals_strarray, sliceb);

  sub test_flush : int ($file : string) {
    
    my $io_file = SPVM::IO::File->open($file, ">");
    
    $io_file->print("He");
    $io_file->flush;
    $io_file->print("llo");
    $io_file->flush;
    
    return 1;
  }

  sub test_auto_flush : int ($file : string) {
    
    my $io_file = SPVM::IO::File->open($file, ">");
    unless ($io_file) {
      return 0;
    }
    
    my $io_file_default : byte = $io_file->auto_flush;
    unless ($io_file_default == 0) {
      return 0;
    }
    
    $io_file->set_auto_flush(1);
    unless ($io_file->auto_flush == 1) {
      return 0;
    }

    $io_file->print("Hello");
    
    return 1;
  }

  sub test_print : int ($file : string) {
    
    my $io_file = SPVM::IO::File->open($file, ">");
    unless ($io_file) {
      return 0;
    }
    
    $io_file->print("Hello");
    
    return 1;
  }

  sub test_print_newline : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, ">");
    unless ($io_file) {
      return 0;
    }
    
    $io_file->print("\n");
    
    return 1;
  }

  sub test_print_long_lines : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, ">");
    unless ($io_file) {
      return 0;
    }
    
    $io_file->print("AAAAAAAAAAAAA\nBBBBBBBBBBBBBBBBBBB\nCCCCCCCCCCCCCCCCCCCCCCCCCCC\nDDDDDDDDDDDDDDDDDDDDDDDDD\nEEEEEEEEEEEEEEEEEEEEEE\nFFFFFFFFFFFFFF\n");
    
    return 1;
  }

  sub test_open : int ($file : string) {
    {
      my $io_file = SPVM::IO::File->open($file, "<");
      unless ($io_file) {
        return 0;
      }
    }
    
    {
      eval {
        SPVM::IO::File->open($file, "ppp");
      };
      
      unless ($@) {
        return 0;
      }
      $@ = undef;
    }
    
    return 1;
  }

  sub test_read : int ($file : string) {
    {
      my $io_file = SPVM::IO::File->open($file, "<");
      unless ($io_file) {
        die "Can't open file $file";
      }
      
      my $buffer = new byte[5];
      {
        my $read_length = $io_file->read($buffer);
        unless ($buffer eq "abcd\n") {
          return 0;
        }
        unless ($read_length == 5) {
          return 0;
        }
      }
      
      {
        my $read_length = $io_file->read($buffer);
        unless ($buffer eq "fghi\n") {
          return 0;
        }
        unless ($read_length == 5) {
          return 0;
        }
      }
      {
        my $read_length = $io_file->read($buffer);
        unless (sliceb($buffer, 0, 4) eq "klm\n") {
          return 0;
        }
        unless ($read_length == 4) {
          return 0;
        }
      }
    }

    return 1;
  }

  sub test_readline : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, "<");
    unless ($io_file) {
      die "Can't open file $file";
    }
    
    {
      my $line = $io_file->readline;
      unless ($line eq "abcd\n") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      unless ($line eq "fghi\n") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      unless ($line eq "klm\n") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_readline_while : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, "<");
    unless ($io_file) {
      die "Can't open file $file";
    }
    
    my $lstrings = SPVM::StringList->new;
    while (my $line = $io_file->readline) {
      $lstrings->push($line);
    }
    my $strings = $lstrings->to_array;
    
    unless (equals_strarray($strings, ["abcd\n", "fghi\n", "klm\n"])) {
      return 0;
    }
    
    return 1;
  }

  sub test_readline_eof : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, "<");
    unless ($io_file) {
      die "Can't open file $file";
    }
    
    {
      my $line = $io_file->readline;
      unless ($line eq "abcd\n") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      unless ($line eq "fghi\n") {
        return 0;
      }
    }
    
    {
      my $line = $io_file->readline;
      unless ($line eq "\n") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      unless ($line eq "klm") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_readline_long_line : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, "<");
    unless ($io_file) {
      die "Can't open file $file";
    }
    
    {
      my $line = $io_file->readline;
      unless ($line eq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      unless ($line eq "fghi\n") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      unless ($line eq "klm\n") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_readline_chomp_lf : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, "<");
    unless ($io_file) {
      die "Can't open file $file";
    }
    
    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "abcd") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "fghi") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "klm") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_readline_chomp_lf_while : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, "<");
    unless ($io_file) {
      die "Can't open file $file";
    }
    
    my $lstrings = SPVM::StringList->new;
    while (my $line = $io_file->readline) {
      $line = chomp_lf($line);
      $lstrings->push($line);
    }
    my $strings = $lstrings->to_array;
    
    unless (equals_strarray($strings, ["abcd", "fghi", "klm"])) {
      return 0;
    }
    
    return 1;
  }

  sub test_readline_chomp_lf_eof : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, "<");
    unless ($io_file) {
      die "Can't open file $file";
    }
    
    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "abcd") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "fghi") {
        return 0;
      }
    }
    
    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "klm") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_readline_chomp_lf_long_line : int ($file : string) {
    my $io_file = SPVM::IO::File->open($file, "<");
    unless ($io_file) {
      die "Can't open file $file";
    }
    
    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "fghi") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line eq "klm") {
        return 0;
      }
    }

    {
      my $line = $io_file->readline;
      $line = chomp_lf($line);
      unless ($line == undef) {
        return 0;
      }
    }
    return 1;
  }

  sub test_slurp : int ($file : string) {
    {
      my $io_file = SPVM::IO::File->open($file, "<");
      
      my $string = $io_file->slurp($file);
      
      unless ($string eq "abcd\nfghi\nklm\n") {
        return 0;
      }
    }
    
    return 1;
  }
}