### ----------------------------------------------------
### -- Algorithm::XGBoost
### -- Licenses: Artistic-2.0
### -- Authors: Itsuki Toyota
### -- File: t/01-basic.rakutest
### ----------------------------------------------------
use Test;
use Algorithm::XGBoost;
use Algorithm::XGBoost::DMatrix;
use Algorithm::XGBoost::Model;

dies-ok { Algorithm::XGBoost.new; }
dies-ok { Algorithm::XGBoost::Model.new; }
dies-ok { Algorithm::XGBoost::DMatrix.new; }
lives-ok { Algorithm::XGBoost.version; }

subtest {
    my $dmat = Algorithm::XGBoost::DMatrix.from-file("{$*PROGRAM.parent.absolute}/../misc/agaricus.txt.train");
    is $dmat.num-row, 6513;
    is $dmat.num-col, 127;
    my $model = Algorithm::XGBoost.train($dmat, 10);
    is $model.num-feature, 127;

    my @test[2;2] = [[0e0,0e0],[0e0,1e0]];
    my $test = Algorithm::XGBoost::DMatrix.from-matrix(@test);
    is $model.predict($test), (0.9858561754226685, 0.9858561754226685);
}, "Make sure SYNOPSIS works fine";

subtest {
    my $dmat = Algorithm::XGBoost::DMatrix.from-file("{$*PROGRAM.parent.absolute}/../misc/agaricus.txt.train");
    is $dmat.num-row, 6513;
    is $dmat.num-col, 127;
    my $model = Algorithm::XGBoost.train($dmat, 10);
    is $model.num-feature, 127;

    my @test = [[0e0,0e0],[0e0,1e0]];
    my $test = Algorithm::XGBoost::DMatrix.from-matrix(@test);
    is $model.predict($test), (0.9858561754226685, 0.9858561754226685);
}, "Make sure SYNOPSIS (unshaped version) works fine";

subtest {
    my @train[3;2] = [[0e0,0e0],[0e0,1e0],[1e0,0e0]];
    my @y = [1e0, 0e0, 1e0];
    my $dmat = Algorithm::XGBoost::DMatrix.from-matrix(@train, @y);
    is $dmat.num-row, 3;
    is $dmat.num-col, 2;
    my $model = Algorithm::XGBoost.train($dmat, 10);
    is $model.num-feature, 2;

    my @test[2;2] = [[0e0,0e0],[0e0,1e0]];
    my $test = Algorithm::XGBoost::DMatrix.from-matrix(@test);
    is $model.predict($test), (0.9463129639625549, 0.09843720495700836)
}, "Given a label list @y, Then DMatrix.from-matrix should set the labels";

subtest {
    use JSON::Tiny;
    Algorithm::XGBoost.global-config(q[{"verbosity": 2}]);
    my $json = Algorithm::XGBoost.global-config;
    is from-json($json)<verbosity>, 2;
}, ".global-config should set/get verbosity=2";

subtest {
    my @train[3;2] = [[0e0,0e0],[0e0,1e0],[1e0,0e0]];
    my @y = [1e0, 0e0, 1e0];
    my $dmat = Algorithm::XGBoost::DMatrix.from-matrix(@train, @y);
    my $model = Algorithm::XGBoost.train($dmat, 10);
    my @test[2;2] = [[0e0,0e0],[0e0,1e0]];
    my $test = Algorithm::XGBoost::DMatrix.from-matrix(@test);
    my $expected = $model.predict($test);
    my $path = "$*TMPDIR/.raku-xgboost.model";
    $model.save($path);
    my $model2 = Algorithm::XGBoost::Model.load($path);
    my $actual = $model2.predict($test);
    shell("rm $path");
    is $actual, $expected;
}, "When a model is given, Then .save/.load should retain the model";

subtest {
    Algorithm::XGBoost.global-config(q[{"verbosity": 4}]);
    my @train[3;2] = [[0e0,0e0],[0e0,1e0],[1e0,0e0]];
    my @y = [1e0, 0e0, 1e0];
    my $dmat = Algorithm::XGBoost::DMatrix.from-matrix(@train, @y);
    # TODO: Get param from the model
    lives-ok {
        my %param = (:booster("dart"));
        my $model = Algorithm::XGBoost.train($dmat, 10, %param);
    }
}, "When a %param is given, Then .train should use it";

done-testing;


