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

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

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

#-------------------------------------------------------------------------------
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;
#my MongoDB::Cursor $cursor;

# 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');

# Create collection and insert data in it!
my MongoDB::Collection $collection = $database.collection('cl1');
isa-ok( $collection, 'MongoDB::Collection');

$database.run-command: (drop => $collection.name,);

#-------------------------------------------------------------------------------
subtest "Several inserts", {

  # Add records
  $req .= new: (
    insert => $collection.name,
    documents => [
      ( name => 'Jan Klaassen'),
      ( name => 'Piet B'),
      ( name => 'Me T'),
      ( :name('Di D'))
    ]
  );

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

  $req .= new: ( count => $collection.name, query => (name => 'Me T',));
  $doc = $database.run-command($req);
  is $doc<ok>, 1, "count request ok";
  is $doc<n>, 1, 'count 1 record of "Me T"';

  $req<query> = (name => 'Di D',);
  $doc = $database.run-command($req);
  is $doc<n>, 1, 'count 1 record of "Di D"';

  $req<query> = (name => 'Di D',);
  $doc = $database.run-command($req);
  is $doc<n>, 1, '1 record of "Jan Klaassen"';

  # Add next few records
  $req .= new: (
    insert => $collection.name,
    documents => [
      (:name('n1'), :test(0)),  (:name('n2'), :test(0)),
      (:name('n3'), :test(0)),  (:name('n4'), :test(0)),
      (:name('n5'), :test(0)),  (:name('n6'), :test(0))
    ]
  );

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

  $req .= new: ( :count($collection.name), :query((:test(0),)));
  $doc = $database.run-command($req);
  is $doc<n>, 6, '6 records of Test(0)';

  $req .= new: ( :count($collection.name), :query((:name('Di D'),)));
  $doc = $database.run-command($req);
  is $doc<n>, 1, "1 record of name('Di D')";
};

#-------------------------------------------------------------------------------
# Drop current collection twice
subtest 'drop collection two times', {

  $req .= new: (drop => $collection.name);
  $doc = $database.run-command($req);

  ok $doc<ok>.Bool == True, 'Dropping cl1 ok';
  #say $doc.perl;
  is $doc<ns>, 'test.cl1', 'Dropped collection';
  is $doc<nIndexesWas>, 1, 'Number of dropped indexes';

  # Do it a second time
  try {
    $doc = $database.run-command($req);
    CATCH {
      when X::MongoDB {
        ok $_.message ~~ m/ns \s+ not \s* found/, 'Collection cl1 not found';
      }
    }
  }
};

#-------------------------------------------------------------------------------
$client.cleanup;
done-testing();





=finish

#-------------------------------------------------------------------------------
# Create using illegal collection name
try {
  $database.create-collection('abc-def and a space');
  CATCH {
    when X::MongoDB {
      ok $_.message ~~ m/Illegal \s* collection \s* name/, 'Illegal collection name';
    }
  }
}

#-------------------------------------------------------------------------------
# Drop collection and create one explicitly with some parameters
#$collection.drop;
$database.create-collection( 'cl1', :capped, :size(1000));

# Fill collection with 100 records. Should be too much.
for ^200 -> $i, $j {
  my %d = %( code1 => 'd' ~ $i, code2 => 'n' ~ (100 - $j));
  $collection.insert(%d);
}

# Find all documents
my MongoDB::Cursor $cursor = $collection.find();
isnt $cursor.count, 100, 'Less than 100 records in collection';

#-------------------------------------------------------------------------------
# Drop collection and create one explicitly with other parameters
$collection.drop;
$database.create-collection( 'cl1', :capped, :size(1000), :max(10));

# Fill collection with 100 records. Should be too much.
for ^200 -> $i, $j {
  my %d = %( code1 => 'd' ~ $i, code2 => 'n' ~ (100 - $j));
  $collection.insert(%d);
}

# Find all documents
$cursor = $collection.find();
is $cursor.count, 10, 'Only 10 records in collection';

#-------------------------------------------------------------------------------
# Cleanup
$req .= new: ( dropDatabase => 1 );
$doc = $database.run-command($req);
say $doc.perl;

info-message("Test $?FILE stop");
sleep .2;
drop-all-send-to();
done-testing();


