### ----------------------------------------------------
### -- MongoDB
### -- Licenses: Artistic-2.0
### -- Authors: Marcel Timmerman, Paweł Pabian
### -- File: xt/Tests/Basic/160-Server.rakutest
### ----------------------------------------------------
use Test;

use BSON;
use BSON::Document;

use MongoDB;
use MongoDB::Client;
use MongoDB::ServerPool::Server;
use MongoDB::Uri;

use Base64;
use OpenSSL::Digest;

#-------------------------------------------------------------------------------
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::Debug));
#set-filter(|<ObserverEmitter Timer Socket>);

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

#-------------------------------------------------------------------------------
my Str $uri = "mongodb://localhost:@server-ports[0]";
my MongoDB::Client $client .= new(:$uri);
my $uri-obj = $client.uri-obj;
my Str $host = $uri-obj.servers[0]<host>;
my Int $port = $uri-obj.servers[0]<port>.Int;

my MongoDB::ServerPool::Server $server;

#-------------------------------------------------------------------------------
subtest "Server creation", {
#  $server .= new( :$client-key, :$host, :$port);
  $server .= new( :$host, :$port);
  isa-ok $server, MongoDB::ServerPool::Server,
    '.new( :client-key, :host, :port)';
  is $server.name, "$host:$port", '.name() = ' ~ $server.name();
  is $server.host, $host, '.host() = ' ~ $server.host();
  is $server.port, $port, '.port() = ' ~ $server.port();
  ok $server.server-is-registered, '.server-is-registered()';
}

#-------------------------------------------------------------------------------
subtest "Server manipulations", {
  is $server.get-data('status'), ST-Unknown, '.get-data() one item';
  my $h = $server.get-data(<status is-master non-exist-item>);
  is $h.keys.elems, 2, '.get-data() 2 items';
  is-deeply $h, %(:status(ST-Unknown), :!is-master), '.get-data() data';

  $server.set-data( :new-item1(10) :new-item2(11));
  is $server.get-data('new-item1'), 10, '.set-data()';
  $h = $server.get-data;
  is $h.keys.elems, 5, '.get-data() all items';
}

#-------------------------------------------------------------------------------
subtest "Socket manipulations", {
  my MongoDB::Uri $uri-obj .= new(:uri("mongodb://$server.name()"));
  my MongoDB::SocketPool::Socket $socket = $server.get-socket(
    :$uri-obj#, :!authenticate
  );
  isa-ok $socket, MongoDB::SocketPool::Socket;
}

#`{{
#-------------------------------------------------------------------------------
subtest "Socket manipulations", {
  my MongoDB::Header $header .= new;

  ( my Buf $encoded-query, my Int $request-id) = $header.encode-query(
    'admin.$cmd', $monitor-command, :number-to-return(1)
  );

  $socket.send($encoded-query);
  my Buf $size-bytes = $socket.receive-check(4);
  my Int $response-size = $size-bytes.read-int32( 0, LittleEndian) - 4;
  my Buf $server-reply = $size-bytes ~ $socket.receive-check($response-size);
  my BSON::Document $result = $header.decode-reply($server-reply);
  is $result<number-returned>, 1, '.send() / .receive-check()';
  is $result<documents>[0]<ok>, 1, 'document is ok';

  ok $socket.check-open, '.check-open()';

  my MongoDB::Client $client = $clients{$clients.keys[0]};
  my MongoDB::Database $database = $client.database('test');

#note $result.perl;
}
}}

#-------------------------------------------------------------------------------
info-message("Test $?FILE stop");
done-testing();


