# This test script reads in the tab-sep files of test values generated by
# testvalues-generator.c and mv-testvalues-generator.c to make sure the bound
# GSL functions are producing results identical to raw C calls.


use strict;
use warnings FATAL => "all";
use 5.010_000;
use autodie;

use Test::More tests => 2306;
use Test::Exception;
use Scalar::Util qw/looks_like_number/;

use PDL;
use PDL::GSL::RNG;
use PDL::GSL::Randist;

for my $file (qw{t/testvalues.txt t/mvtestvalues.txt}) {
    open my $fh, '<', $file;
    my $seed = <$fh>;
    chomp($seed);

    my $rng = PDL::GSL::RNG->new('taus');
    $rng->set_seed($seed);

    while (defined(my $line = <$fh>)){
        chomp $line;
        my ($funname, @others) = split /\t/, $line;
        # say $line;

        my $c_val_isfinite = $others[-1] !~ /nan|inf|1\.#IND|1\.#INF/;
        my $c_val = $c_val_isfinite ? pdl $others[-1] : pdl "nan";

        my @args = map { looks_like_number $_ ? $_ : pdl $_ } @others[0 .. $#others - 1];

        # say join "\n", $c_val, @args;

        $funname =~ s/gsl_//;
        if (! exists $PDL::GSL::Randist::{$funname}){
            die "can't find $funname";
        }
        if ($funname !~ /pdf|P|Q|Pinv|Qinv$/){ # is a sampler
            # say "$line\n$c_val\n" . join "\t", @args;
            my $p_val = $PDL::GSL::Randist::{$funname}->($rng, @args);
            ok(
                all(abs($p_val - $c_val) < .000_000_1),
                "$funname (args: @args) (p: $p_val) (c: $c_val)"
            );
        }
        else{
            my $p_val = $PDL::GSL::Randist::{$funname}->(@args);
            my $p_val_isfinite = $p_val->isfinite();
            ok (
                (
                    ! $c_val_isfinite && ! $p_val_isfinite
                ) # both nan/inf/bad
                ||
                (
                    $c_val_isfinite && $p_val_isfinite 
                    && 
                    all(abs($p_val - $c_val) < .000_000_1)
                ),
                "$funname (args: @args) (p: $p_val) (c: $c_val)",
            );

        }
    }
    close $fh;
}

