### ----------------------------------------------------
### -- MongoDB
### -- Licenses: Artistic-2.0
### -- Authors: Marcel Timmerman, Paweł Pabian
### -- File: xt/Tests/500-Cursor.rakutest
### ----------------------------------------------------
use lib 'lib';
use Test;

use MongoDB;
use MongoDB::Client;
use MongoDB::Database;
use BSON::Document;
use MongoDB::Cursor;

#-------------------------------------------------------------------------------
my Str $log-path = @*ARGS[0];
my Version $server-version .= new(@*ARGS[1]);
my @server-ports = @*ARGS[2..*];

#-------------------------------------------------------------------------------
drop-send-to('mongodb');
drop-send-to('screen');
#modify-send-to( 'screen', :level(MongoDB::MdbLoglevels::Trace));
my $handle = $log-path.IO.open( :mode<wo>, :append);
add-send-to( 'mdb', :to($handle), :min-level(MongoDB::MdbLoglevels::Trace));
set-filter(|<ObserverEmitter Timer Monitor Socket SocketPool Server ServerPool>);

info-message("Test $?FILE start");

my BSON::Document $req;
my BSON::Document $doc;

# single server tests => one server key
my Str $uri = "mongodb://localhost:@server-ports[0]";
my MongoDB::Client $client .= new(:$uri);
my MongoDB::Database $database = $client.database('test');
my MongoDB::Database $db-admin = $client.database('admin');
my MongoDB::Collection $collection = $database.collection('names');

# Drop database first, not checked for success.
$database.run-command(BSON::Document.new: (dropDatabase => 1));

#-------------------------------------------------------------------------------
subtest "cursor iteration", {

  $req .= new: (
    insert => 'names',
    documents => [ (
        name => 'Larry',
        surname => 'Wall',
      ), (
        name => 'Damian',
        surname => 'Conway',
      ), (
        name => 'Jonathan',
        surname => 'Worthington',
      ), (
        name => 'Moritz',
        surname => 'Lenz',
      ), (
        name => 'Many',
        surname => 'More',
      ), (
        name => 'piet',
        surname => 'jansen',
      ), (
        name => 'marcel',
        surname => 'timmerman',
      ), (
        name => 'foo',
        surname => 'bar',
      ),
    ]
  );

  $doc = $database.run-command($req);
  is $doc<ok>, 1, "Result is ok";
  is $doc<n>, 8, "Inserted $doc<n> documents";

  
  my MongoDB::Cursor $cursor;
  if $server-version >= v5.1.0 {
    $doc = $database.run-command: (:find<names>,);
    $cursor := MongoDB::Cursor.new( :$client, :cursor-doc($doc<cursor>));
  }
  
  else {
    $cursor := $collection.find;
  }

#TODO: are documents returned in same order as insert?
  my Int $c = 0;
  for $cursor -> BSON::Document $d {
    is $d<name>, $req<documents>[$c++]<name>, $d<name>;
  }

  if $server-version < v3.0.0 {
    skip "listCollections not available in version $server-version", 1;
  }

  else {
    $doc = $database.run-command(BSON::Document.new: (listCollections => 1));
    my MongoDB::Cursor $c2 .= new( :$client, :cursor-doc($doc<cursor>));

    my BSON::Document $d = $c2.iterator.pull-one;

    # more info after version 3.6 returned
    if $server-version >= v3.6.0 {
      if $server-version < v4.0.5 {
        is $d<idIndex><ns>, 'test.names', "index on $d<idIndex><ns>";
      }

      else {
        skip "no namespace field in idIndex of listCollections in version $server-version", 1;
      }
    }

    is $d<name>, 'names', "set collection name";

    # no system collections returned after version 3.6
    if $server-version < v3.6.0 {
      $d = $c2.iterator.pull-one;
      is $d<name>, 'system.indexes', "system collection name";
    }

    else {
      skip "no system collections from listCollections in version $server-version", 1;
    }
  }
}


#-------------------------------------------------------------------------------
# Cleanup
done-testing;


