### ----------------------------------------------------
### -- Red
### -- Licenses: Artistic-2.0
### -- Authors: Fernando Correa de Oliveira
### -- File: t/26-classify.rakutest
### ----------------------------------------------------
use Test;
use Red;

model Bla {
    has UInt $!id  is serial;
    has Str  $.bla is column;
}

my $*RED-DEBUG          = $_ with %*ENV<RED_DEBUG>;
my $*RED-DEBUG-RESPONSE = $_ with %*ENV<RED_DEBUG_RESPONSE>;
my @conf                = (%*ENV<RED_DATABASE> // "SQLite").split(" ");
my $driver              = @conf.shift;
my $*RED-DB             = database $driver, |%( @conf.map: { do given .split: "=" { .[0] => val .[1] } } );

schema(Bla).drop;
Bla.^create-table;
Bla.^create: :bla<test1>;
Bla.^create: :bla<test1>;
Bla.^create: :bla<test2>;

my %a := Bla.^all.classify({ .bla });
is %a.elems, 2;
is %a<test1>.elems, 2;
is %a<test2>.elems, 1;
my %b := Bla.^all.map(*.bla).classify({ .self });
is %b.elems, 2;
is %b<test1>.elems, 2;
is %b<test2>.elems, 1;
my %c := Bla.^all.map(*.bla).classify(* eq "test1");
is %c.elems, 2;
is %c.keys.Seq.sort.map({
    when "True"  { True      }
    when "False" { False     }
    default      { .Int.Bool }
}), (False, True);
without %*ENV<RED_DATABASE> {
    is %c{1}.elems, 2;
    is %c{0}.elems, 1;
}
is-deeply Bla.^all.classify(*.bla).Bag, bag(<test1 test1 test2>);
is-deeply Bla.^all.classify(*.bla).Set, set(<test1 test2>);
is-deeply Bla.^all.map(*.bla).Bag, bag(<test1 test1 test2>);
is-deeply Bla.^all.map(*.bla).Set, set(<test1 test2>);

my %d := Bla.^all.classify({ .bla, .id });
is %d.elems, 2;
isa-ok %d<test1>, Red::ResultAssociative;
is %d<test1>.elems, 2;
is %d<test1>.keys, <1 2>;

isa-ok %d<test2>, Red::ResultAssociative;
is %d<test2>.elems, 1;
is %d<test2>.keys, <3>;

my %e := Bla.^all.classify({ .bla }, :reduce{ .elems });
is %e.elems, 2;
isa-ok %e<test1>, Int;
is %e<test1>, 2;

isa-ok %e<test2>, Int;
is %e<test2>, 1;

# TODO: Make it work
# my %f := Bla.^all.classify({ .bla }, :reduce{ .map: *.id.sum });
# is %f.elems, 2;
# isa-ok %f<test1>, Int;
# is %f<test1>, 2;
#
# isa-ok %f<test2>, Int;
# is %f<test2>, 1;

done-testing;


