# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl test.pl'

######################### We start with some black magic to print on failure.

# Change 1..1 below to 1..last_test_to_print .
# (It may become useful if the test is moved to ./t subdirectory.)

BEGIN { $| = 1; print "0..48\n"; }
END {print "not ok 0\n" unless $loaded;}
use RefDB::Client;
$loaded = 1;
print "ok 0\n";

######################### End of black magic.

# set a few initial params
my $auser = "root";          # must match your database server
my $apasswd = "";            # must match your database server
my $server_ip = "127.0.0.1"; # where refdbd runs
my $port = "9734";           # where refdbd listens

# these are used internally and should be ok
my $cuser = "testuser"; 
my $cpasswd = "pass";
my $puser = "pickuser"; 
my $ppasswd = "pass";
my $testdb = "perltest";
my $adduser_ip = "localhost";
my $bibencoding = "UTF-8";
my $author_regex = "";
my $keyword_regex = "";
my $periodical_regex = "";

## ask user for connection parameters
my $input;

print "This test script requires a running refdbd server that we can connect to. Please provide the following connection parameters (hitting ENTER will use the defaults):\n\n";
print "username of database administrator [$auser]:";
chomp($input = <STDIN>);

if (length($input) > 0) {
    $auser = $input;
}

print "password of database administrator [$apasswd]:";
chomp($input = <STDIN>);

if (length($input) > 0) {
    $apasswd = $input;
}

print "IP address of refdbd server [$server_ip]:";
chomp($input = <STDIN>);

if (length($input) > 0) {
    $server_ip = $input;
}

print "port of refdbd server [$port]:";
chomp($input = <STDIN>);

if (length($input) > 0) {
    $port = $input;
}

###
### here the real tests start
###
my $numtest = 1;
my $numok = 1;
my $numtotal = 48;

# password encryption test
print "$numtest..$numtotal: password encryption\n";
$numtest++;

my $enigma = new RefDB::Enigma;

my $scramble;
my $randno = abs(rand() * 6);

if ($randno < 1) {
    $scramble = "012";
}
elsif ($randno < 2) {
    $scramble = "021";
}
elsif ($randno < 3) {
    $scramble = "120";
}
elsif ($randno < 4) {
    $scramble = "102";
}
elsif ($randno < 5) {
    $scramble = "201";
}
else {
    $scramble = "210";
}

for my $i (0 .. 2) {
    $randno = abs(rand() * 93);
    $scramble .= sprintf("-%02d", $randno);
}
$enigma->init("heinzmeier", $scramble);

$enigma->eenc();

my $renigma = new RefDB::Enigma;

$renigma->init($enigma->{encodedpass}, $scramble);

$renigma->eenc();

if ($enigma->{rawpass} eq $renigma->{encodedpass}) {
    print "password encryption ok:$renigma->{encodedpass}\n";
}
else {
    print "password encryption broken\n";
    exit 1;
}

# we need one refdba and two refdbc clients as the
# username/password may differ
my $clienta = new RefDB::Client;

$clienta->set_conninfo($server_ip, $port, $auser, $apasswd, "", "/home/testuser/literature", "/usr/local/share/refdb/css/refdb.css");


my $clientc = new RefDB::Client;

$clientc->set_conninfo($server_ip, $port, $cuser, $cpasswd, "", "/home/testuser/literature", "/usr/local/share/refdb/css/refdb.css");

my $clientcp = new RefDB::Client;

$clientcp->set_conninfo($server_ip, $port, $puser, $ppasswd, "$testdb", "/home/testuser/literature", "/usr/local/share/refdb/css/refdb.css");

# run the refdba:viewstat command to test the connection
print "$numtest..$numtotal: viewstat\n";
$numtest++;

my $summary = $clienta->refdb_viewstat();

if ($clienta->get_status() ne "000") {
    print $clienta->get_status_msg() . "\n";
}
else {
    print "start viewstat result:\n";
    print $clienta->get_data();
    print "end viewstat result:\n";
    print "viewstat result summary: $summary\n";
}

# prepare some database engine specific strings
if ($clienta->get_data() =~ /pgsql/) {
    print "self-adapt to PostgreSQL\n\n";
    $author_regex = ".*";
    $keyword_regex = ".*";
    $periodical_regex = "J.*";
}
elsif ($clienta->get_data() =~ /mysql/) {
    print "self-adapt to MySQL\n\n";
    $author_regex = ".*";
    $keyword_regex = ".*";
    $periodical_regex = "J.*";
}
elsif ($clienta->get_data() =~ /sqlite/) {
    print "self-adapt to SQLite\n\n";
    $author_regex = "%";
    $keyword_regex = "%";
    $periodical_regex = "J%";
}
elsif ($clienta->get_data() =~ /sqlite3/) {
    print "self-adapt to SQLite3\n\n";
    $author_regex = "%";
    $keyword_regex = "%";
    $periodical_regex = "J%";
}
else {
    print "Unknown database engine\n"
}

# add a bibliography style to the database
print "$numtest..$numtotal: addstyle\n";
$numtest++;

my $file = "testdata/refdbteststyle.xml";
#my $file = "testdata/bibtex-invalid.xml";
open IN, "< $file";
while (<IN>) {
    $instring .= $_;
}
close IN;

$summary = $clienta->refdb_addstyle($instring);

print "start addstyle result:\n";
print $clienta->get_data();
print "end addstyle result:\n";
print "addstyle result summary: $summary\n";


# see whether the new style appears in the style list
print "$numtest..$numtotal: liststyle\n";
$numtest++;

$summary = $clienta->refdb_liststyle("");

print "start liststyle result:\n";
print $clienta->get_data();
print "end liststyle result:\n";
print "liststyle result summary: $summary\n";

# retrieve the style again
print "$numtest..$numtotal: getstyle\n";
$numtest++;

$summary = $clienta->refdb_getstyle("refdbteststyle");

print "start getstyle result:\n";
print $clienta->get_data();
print "end getstyle result:\n";
print "getstyle result summary: $summary\n";

# create a new reference database
print "$numtest..$numtotal: createdb\n";
$numtest++;

$summary = $clienta->refdb_createdb("$testdb");

print "start createdb result:\n";
print $clienta->get_data();
print "end createdb result:\n";
print "createdb result summary: $summary\n";

# add users
print "$numtest..$numtotal: adduser\n";
$numtest++;

$summary = $clienta->refdb_adduser($adduser_ip, "$testdb", $cpasswd, $cuser);

print "start adduser result:\n";
print $clienta->get_data();
print "end adduser result:\n";
print "adduser result summary: $summary\n";

# silently add another user for picking refs
$summary = $clienta->refdb_adduser($adduser_ip, "$testdb", $ppasswd, $puser);

# select the new database
print "$numtest..$numtotal: selectdb\n";
$numtest++;

$summary = $clientc->refdb_selectdb("$testdb");

print "start selectdb result:\n";
print $clientc->get_data();
print "end selectdb result:\n";
print "selectdb result summary: $summary\n";

# add RIS datasets
print "$numtest..$numtotal: addref (RIS data)\n";
$numtest++;

my $risdata = new RefDB::Risdata;

$risdata->read_ris("testdata/pubmed.ris");

$summary = $clientc->refdb_addref(undef, $risdata, "ris", "ISO-8859-1");

print "start addref ris result:\n";
print $clientc->get_data();
print "end addref ris result:\n";
print "addref ris result summary: $summary\n";

# wait until background process releases lock on SQLite database
print "now sleep for five seconds...\n";
sleep 5;
print "done\n";

# add risx datasets
print "$numtest..$numtotal: addref (risx data)";
$numtest++;

my $risxstring;

open IN, "< testdata/alltypes.xml";
while (<IN>) {
    $risxstring .= $_;
}
close IN;

$summary = $clientc->refdb_addref(undef, $risxstring, "risx", undef);

print "start addref risx result:\n";
print $clientc->get_data();
print "end addref risx result:\n";
print "addref risx result summary: $summary\n";


# add xnote datasets
print "$numtest..$numtotal: addnote\n";
$numtest++;

my $xnotestring;

open IN, "< testdata/xnoteset.xml";
while (<IN>) {
    $xnotestring .= $_;
}
close IN;

$summary = $clientc->refdb_addnote(undef, $xnotestring);

print "start addnote result:\n";
print $clientc->get_data();
print "end addnote result:\n";
print "addnote result summary: $summary\n";

# add link
print "$numtest..$numtotal: addlink\n";
$numtest++;

$summary = $clientc->refdb_addlink(":NID:=1 :CK:=MILLER1999");

print "start addlink result:\n";
print $clientc->get_data();
print "end addlink result:\n";
print "addlink result summary: $summary\n";

# count references
print "$numtest..$numtotal: countref\n";
$numtest++;

$summary = $clientc->refdb_countref("", "", ":ID:>0");

print "start countref result:\n";
print $clientc->get_data();
print "end countref result:\n";
print "countref result summary: $summary\n";

# count notes
print "$numtest..$numtotal: countnote\n";
$numtest++;

$summary = $clientc->refdb_countnote("", "", ":NID:>0");

print "start countnote result:\n";
print $clientc->get_data();
print "end countnote result:\n";
print "countnote result summary: $summary\n";

# retrieve references
print "$numtest..$numtotal: getref as ris\n";
$numtest++;

$summary = $clientc->refdb_getref("ris", "AB", undef, "", "ISO-8859-1", "", "", "f", ":ID:=1");

print "start getref result:\n";
print $clientc->get_data();
print "end getref result:\n";
print "getref result summary: $summary\n";

# retrieve references with limit and offset
print "$numtest..$numtotal: getref as risx using limit:offset\n";
$numtest++;

$summary = $clientc->refdb_getref("risx", "AB", undef, "", "ISO-8859-1", "10:5", "X", "t", ":ID:>0");

print "start getref limit:offset result:\n";
print $clientc->get_data();
print "end getref limit:offset result:\n";
print "getref result summary: $summary\n";

# retrieve notes
print "$numtest..$numtotal: getnote\n";
$numtest++;

$summary = $clientc->refdb_getnote("xnote", "AB", undef, "UTF-8", "", "X", ":ID:=1");

print "start getnote result:\n";
print $clientc->get_data();
print "end getnote result:\n";
print "getnote result summary: $summary\n";

# retrieve notes using limit:offset
print "$numtest..$numtotal: getnote limit:offset\n";
$numtest++;

$summary = $clientc->refdb_getnote("xnote", "AB", undef, "UTF-8", "1:1", "X", ":ID:>0");

print "start getnote limit:offset result:\n";
print $clientc->get_data();
print "end getnote limit:offset result:\n";
print "getnote limit:offset result summary: $summary\n";

# test the refdbc:checkref command
print "$numtest..$numtotal: checkref\n";
$numtest++;

$summary = $clientc->refdb_checkref($risdata, "ris", "ISO-8859-1", "scrn");

print "start checkref result:\n";
print $clientc->get_data();
print "end checkref result:\n";
print "checkref result summary: $summary\n";


# test the refdbc:pickref command
print "$numtest..$numtotal: pickref\n";
$numtest++;

$summary = $clientcp->refdb_pickref("1-5");

print "start pickref result:\n";
print $clientcp->get_data();
print "end pickref result:\n";
print "pickref result summary: $summary\n";


# test the refdba:listuser command
print "$numtest..$numtotal: listuser\n";
$numtest++;

$summary = $clienta->refdb_listuser("$testdb");

print "start listuser result:\n";
print $clienta->get_data();
print "end listuser result:\n";
print "listuser result summary: $summary\n";

# test the refdbc:dumpref command
print "$numtest..$numtotal: dumpref\n";
$numtest++;

$summary = $clientcp->refdb_dumpref("1-5");

print "start dumpref result:\n";
print $clientcp->get_data();
print "end dumpref result:\n";
print "dumpref result summary: $summary\n";


# use the refdbc:whichdb command to see the total number of refs
print "$numtest..$numtotal: whichdb\n";
$numtest++;

$summary = $clientc->refdb_whichdb();

print "start whichdb result:\n";
print $clientc->get_data();
print "end whichdb result:\n";
print "whichdb result summary: $summary\n";

# test the refdbc:listdb command to list available databases
print "$numtest..$numtotal: listdb\n";
$numtest++;

$summary = $clientc->refdb_listdb("");

print "start listdb result:\n";
print $clientc->get_data();
print "end listdb result:\n";
print "listdb result summary: $summary\n";


# create a bibliography from a TeX document (or rather, from the .aux file)
print "$numtest..$numtotal: getbib (bibtex)\n";
$numtest++;

$file = "testdata/bibtest.aux";
my $idstring = $clientc->id_from_aux($file);

$summary = $clientc->refdb_texbib("refdbteststyle", $idstring);

print "start texbib result:\n";
print $clientc->get_data();
print "end texbib result:\n";
print "texbib result summary: $summary\n";

# create a formatted bibliography
print "$numtest..$numtotal: getbib (cooked DocBook)\n";
$numtest++;

my $instring;
my $file = "testdata/refdbtest.id.xml";
open IN, "< $file";
while (<IN>) {
    $instring .= $_;
}
close IN;

$summary = $clientc->refdb_dbib("db31", "refdbteststyle", $bibencoding, $instring);

print "start dbib result:\n";
print $clientc->get_data();
print "end dbib result:\n";
print "dbib result summary: $summary\n";

# create a raw bibliography
print "$numtest..$numtotal: getrefx (raw DocBook)\n";
$numtest++;

my $instring;
my $file = "testdata/refdbtest.id.xml";
open IN, "< $file";
while (<IN>) {
    $instring .= $_;
}
close IN;

$summary = $clientc->refdb_getrefx("db31", $bibencoding, $instring);

print "start getrefx result:\n";
print $clientc->get_data();
print "end getrefx result:\n";
print "getrefx result summary: $summary\n";

# get author names
print "$numtest..$numtotal: getau\n";
$numtest++;

$summary = $clientc->refdb_getau("", "freq", $author_regex);

print "start getau result:\n";
print $clientc->get_data();
print "end getau result:\n";
print "getau result summary: $summary\n";

# get editor names
print "$numtest..$numtotal: geted\n";
$numtest++;

$summary = $clientc->refdb_geted("", "relfreq", $author_regex);

print "start geted result:\n";
print $clientc->get_data();
print "end geted result:\n";
print "geted result summary: $summary\n";

# get series editor names
print "$numtest..$numtotal: getas\n";
$numtest++;

$summary = $clientc->refdb_getas("", "freq", $author_regex);

print "start getas result:\n";
print $clientc->get_data();
print "end getas result:\n";
print "getas result summary: $summary\n";

# get keywords
print "$numtest..$numtotal: getkw\n";
$numtest++;

$summary = $clientc->refdb_getkw("", "freq", $keyword_regex);

print "start getkw result:\n";
print $clientc->get_data();
print "end getkw result:\n";
print "getkw result summary: $summary\n";

# get keywords with limit and offset
print "$numtest..$numtotal: getkw using limit:offset\n";
$numtest++;

$summary = $clientc->refdb_getkw("5:10", "relfreq", $keyword_regex);

print "start getkw limit:offset result:\n";
print $clientc->get_data();
print "end getkw limit:offset result:\n";
print "getkw limit:offset result summary: $summary\n";

# get journal names
print "$numtest..$numtotal: getjo\n";
$numtest++;

$summary = $clientc->refdb_getjo("f", "", "freq", $periodical_regex);

print "start getjo result:\n";
print $clientc->get_data();
print "end getjo result:\n";
print "getjo result summary: $summary\n";

# get journal names (full)
print "$numtest..$numtotal: getjf\n";
$numtest++;

$summary = $clientc->refdb_getjf("f", "", "freq", $periodical_regex);

print "start getjf result:\n";
print $clientc->get_data();
print "end getjf result:\n";
print "getjf result summary: $summary\n";

# get journal names (user abbrev 1)
print "$numtest..$numtotal: getj1\n";
$numtest++;

$summary = $clientc->refdb_getj1("f", "", "freq", $periodical_regex);

print "start getj1 result:\n";
print $clientc->get_data();
print "end getj1 result:\n";
print "getj1 result summary: $summary\n";

# get journal names (user abbrev 2)
print "$numtest..$numtotal: getj2\n";
$numtest++;

$summary = $clientc->refdb_getj2("f", "", "freq", $periodical_regex);

print "start getj2 result:\n";
print $clientc->get_data();
print "end getj2 result:\n";
print "getj2 result summary: $summary\n";

# update journal names
print "$numtest..$numtotal: updatejo\n";
$numtest++;

$summary = $clientc->refdb_updatejo(":JA:=\'Biochem.Pharmacol.\' :JF:=\'Biochemical Pharmacology\'");

print "start updatejo result:\n";
print $clientc->get_data();
print "end updatejo result:\n";
print "updatejo result summary: $summary\n";

# run keyword scan
print "$numtest..$numtotal: scankw\n";
$numtest++;

$summary = $clienta->refdb_scankw("perltest");

# take a good nap until the keyword scan is done
print "now sleep for 10 seconds...";
sleep 10;
print "done\n";

print "start scankw result:\n";
print $clienta->get_data();
print "end scankw result:\n";
print "scankw result summary: $summary\n";

# delete link
print "$numtest..$numtotal: deletelink\n";
$numtest++;

$summary = $clientc->refdb_deletelink(":NID:=1 :CK:=MILLER1999");

print "start deletelink result:\n";
print $clientc->get_data();
print "end deletelink result:\n";
print "deletelink result summary: $summary\n";


# delete notes
print "$numtest..$numtotal: deletenote\n";
$numtest++;

$summary = $clientc->refdb_deletenote("1");

print "start deletenote result:\n";
print $clientc->get_data();
print "end deletenote result:\n";
print "deletenote result summary: $summary\n";

# delete references
print "$numtest..$numtotal: deleteref\n";
$numtest++;

$summary = $clientc->refdb_deleteref("1-20");

print "start deleteref result:\n";
print $clientc->get_data();
print "end deleteref result:\n";
print "deleteref result summary: $summary\n";

# remove the user
print "$numtest..$numtotal: deleteuser\n";
$numtest++;

$summary = $clienta->refdb_deleteuser($adduser_ip, "$testdb", $cuser);

print "start deleteuser result:\n";
print $clientc->get_data();
print "end deleteuser result:\n";
print "deleteuser result summary: $summary\n";

# silently remove the user that picked refs, and the system db entries
$summary = $clienta->refdb_deleteuser($adduser_ip, "$testdb", $puser);
$summary = $clienta->refdb_deleteuser($adduser_ip, "refdb", $cuser);
$summary = $clienta->refdb_deleteuser($adduser_ip, "refdb", $puser);

# delete the test database
print "$numtest..$numtotal: deletedb\n";
$numtest++;

$summary = $clienta->refdb_deletedb("$testdb");

print "start deletedb result:\n";
print $clienta->get_data();
print "end deletedb result:\n";
print "deletedb result summary: $summary\n";


# add reserved journal words to the system database
print "$numtest..$numtotal: addword";
$numtest++;

$summary = $clienta->refdb_addword("BIMMEL BAMMEL BUMMEL");

print "start addword result:\n";
print $clienta->get_data();
print "end addword result:\n";
print "addword result summary: $summary\n";


# test the refdba:listword command
print "$numtest..$numtotal: listword\n";
$numtest++;

$summary = $clienta->refdb_listword("");

print "start listword result:\n";
print $clienta->get_data();
print "end listword result:\n";
print "listword result summary: $summary\n";


# remove the reserved journal words again
print "$numtest..$numtotal: deleteword\n";
$numtest++;

$summary = $clienta->refdb_deleteword("BIMMEL BAMMEL BUMMEL");

print "start deleteword result:\n";
print $clienta->get_data();
print "end deleteword result:\n";
print "deleteword result summary: $summary\n";

# delete the bibliography style
print "$numtest..$numtotal: deletestyle\n";
$numtest++;

$summary = $clienta->refdb_deletestyle("refdbteststyle");

print "start deletestyle result:\n";
print $clienta->get_data();
print "end deletestyle result:\n";
print "deletestyle result summary: $summary\n";

# reconfigure the server
print "$numtest..$numtotal: confserv\n";
$numtest++;

$summary = $clienta->refdb_confserv("ping");

print "start confserv result:\n";
print $clienta->get_data();
print "end confserv result:\n";
print "confserv result summary: $summary\n";

print "we're done\n";

exit 0;

