#!/bin/sh
#
# Copyright (C) 2000-2022 Kern Sibbald
# License: BSD 2-Clause; see file LICENSE-FOSS
#
# Attempt to backup and restore a file with the bpipe plugin
#
TestName="plugin-test"
JobName=pluginTest
. scripts/functions

scripts/cleanup
scripts/copy-plugin-confs
make -C $src/src/plugins/fd install install-test-plugin
if [ $? -ne 0 ]; then
    print_debug "Failed to build and install test-plugin!"
    exit 1
fi

file=encrypt-bug.jpg
rm -rf ${cwd}/tmp/*
echo "${cwd}/README" >${cwd}/tmp/file-list

$bperl -e 'add_attribute("$conf/bacula-sd.conf", "MaximumFileIndex", "48KB", "Device")'

start_test

cat <<END_OF_DATA >${cwd}/tmp/bconcmds
@output /dev/null
messages
@$out ${cwd}/tmp/log1.out
label storage=File1 volume=TestVolume001
setdebug level=150 client=$CLIENT
estimate job=$JobName level=Full
setdebug level=50 client=$CLIENT
run job=$JobName storage=File1 yes
wait
status client=$CLIENT
messages
setdebug level=50 trace=1 client=$CLIENT
run job=TestPluginTest storage=File1 yes
wait
run job=$JobName fileset=TestPluginSetAcceptFile1 storage=File1 yes
wait
status client=$CLIENT
messages
setdebug level=50 trace=0 client=$CLIENT
quit
END_OF_DATA


run_bacula

cat <<END_OF_DATA >${cwd}/tmp/bconcmds
@$out $tmp/list
llist pluginrestoreconf jobid=2
@$out $tmp/conf
llist pluginrestoreconf jobid=2 id=4
@$out $tmp/events.all
.jlist fileevents jobid=2
@$out $tmp/events.1
.jlist fileevents jobid=2 fileindex=4
@$out $tmp/events.2
.jlist fileevents jobid=2 type=d
@$out $tmp/events.3
.jlist fileevents jobid=2 severity=101
quit
END_OF_DATA

run_bconsole

grep "{" $tmp/events.all | perl -MJSON -e '$j = JSON::decode_json(<>); exit (scalar(@{$j->{data}}) == 11)'
if [ $? != 1 ]; then
    print_debug "ERROR: Should find valid json output in $tmp/events.all"
    estat=1
fi

grep "{" $tmp/events.1 | perl -MJSON -e '$j = JSON::decode_json(<>); exit (scalar(@{$j->{data}}) == 1)'
if [ $? != 1 ]; then
    print_debug "ERROR: Should find valid json output in $tmp/events.1"
    estat=1
fi

grep "{" $tmp/events.2 | perl -MJSON -e '$j = JSON::decode_json(<>); exit (scalar(@{$j->{data}}) == 0)'
if [ $? != 1 ]; then
    print_debug "ERROR: Should find valid json output in $tmp/events.2"
    estat=1
fi

grep "{" $tmp/events.3 | perl -MJSON -e '$j = JSON::decode_json(<>); exit (scalar(@{$j->{data}}) == 0)'
if [ $? != 1 ]; then
    print_debug "ERROR: Should find valid json output in $tmp/events.3"
    estat=1
fi

grep string1 $tmp/conf

if [ $? -ne 0 ]; then
    print_debug "ERROR: Should find string1 in the RestoreObject $tmp/conf"
    estat=1
fi

cat <<EOF >$tmp/obj
string1="My string"
string2="My other string"
req=no
ok=no
EOF

cat <<END_OF_DATA >${cwd}/tmp/bconcmds
messages
@# 
@# now do a restore
@#
@$out ${cwd}/tmp/log2.out
setdebug level=50 client=$CLIENT
restore fileset=pluginSet where=${cwd}/tmp  select all storage=File1 done
yes
wait
setdebug level=0 client=$CLIENT
messages
quit
END_OF_DATA

run_bconsole

stop_bacula

# ****FIXME**** test if the restore of the two files is OK

#
# Remove plugin so we can try the restore without the plugin
#
mv -f ${cwd}/bin/plugins/bpipe-fd.so ${cwd}/bin/plugins/bpipe-fd.sox

cat <<END_OF_DATA >${cwd}/tmp/bconcmds
@$out ${cwd}/tmp/log2.out
@# remove plugin
@exec "sh -c 'rm -f ${cwd}/bin/plugins/bpipe-fd.so'"
@# 
@# now do a restore without the plugin
@#
@$out ${cwd}/tmp/log2.out
@#setdebug level=50 client=$CLIENT
restore fileset=pluginSet where=${cwd}/tmp  select all storage=File1 done
yes
wait
messages
quit
END_OF_DATA

run_bacula -d50
run_bconsole

cat <<END_OF_DATA >${cwd}/tmp/bconcmds
messages
@# 
@# now do a restore
@#
@$out ${cwd}/tmp/log3.out
setdebug level=50 client=$CLIENT trace=1
@putfile obj1 $tmp/obj
list pluginrestoreconf jobid=2 id=4
restore pluginrestoreconf="4:obj1" fileset=TestPluginSet where=${cwd}/tmp  select all storage=File1 done
yes
wait
setdebug level=0 client=$CLIENT trace=0
messages
quit
END_OF_DATA

run_bconsole

grep "My other string" $working/*trace > /dev/null
if [ $? != 0 ]; then
    print_debug "ERROR: Should find plugin restore conf"
    estat=1
fi

cat <<END_OF_DATA >${cwd}/tmp/bconcmds
messages
@# 
@# now do a restore
@#
@$out ${cwd}/tmp/log3.out
setdebug level=50 client=$CLIENT trace=1
restore fileset=TestPluginSet where=${cwd}/tmp  select all storage=File1 done
mod
13
mod
1
My new string
mod
4
yes
mod
5
test1
mod
5
test2
mod
5
test3="this is a test"
yes
yes
wait
setdebug level=0 client=$CLIENT trace=0
messages
quit
END_OF_DATA

run_bconsole

grep "My new string" $working/*trace > /dev/null
if [ $? != 0 ]; then
    print_debug "ERROR: Should find second plugin restore conf"
    estat=1
fi

check_for_zombie_jobs storage=File1
stop_bacula
#
# Restore plugin
#
mv -f ${cwd}/bin/plugins/bpipe-fd.sox ${cwd}/bin/plugins/bpipe-fd.so

check_two_logs
#
# ****FIXME**** test that all three files are restored correctly
#
diff ${cwd}/${file} ${cwd}/tmp/${file}
dstat=$?

diff $working/restore.0 $working/torestore.0
if [ $? != 0 ]; then
    print_debug "ERROR: Restore object difference found"
    dstat=$?
fi

# Look if bRC_OK = 0, bRC_Skip = 7
grep "AcceptFile=takeme.h = 0" $working/*trace > /dev/null
if [ $? != 0 ]; then
    print_debug "ERROR: AcceptFile API problem, look at takeme.h"
    estat=1
fi

grep "excludeme.o = 7" $working/*trace > /dev/null
if [ $? != 0 ]; then
    print_debug "ERROR: AcceptFile API problem, look at excludeme.o"
    estat=1
fi

grep "excludeme.c = 7" $working/*trace > /dev/null
if [ $? != 0 ]; then
    print_debug "ERROR: AcceptFile API problem, look at excludeme.c"
    estat=1
fi

grep '[test1][test2][test3="this is a test"]' $tmp/log3.out > /dev/null
if [ $? != 0 ]; then
    print_debug "ERROR: list plugin option keyword not available in $tmp/log3.out"
    estat=1
fi


# the test-plugin should create a RestoreObject, just check 
# compare restore object before/after
perl -ne '
 chomp();
 if (/Creating RestoreObject/) {
   @elt = split(/\s/, $_, 7);
   $ro{$elt[5]}{clen} = $elt[4];
   $ro{$elt[5]}{cdata} = $elt[6];
 } elsif (/Get RestoreObject/) {
   @elt = split(/\s/, $_, 9);
   $ro{$elt[6]}{glen} = $elt[4];
   $ro{$elt[6]}{gdata} = $elt[8];
 }
 END {
   $err=0;
   delete $ro{"oname=RestoreOptions"};
   if (scalar(keys %ro) == 0) {
     $err = 1;
     print "ERROR: No restore object found\n";
   }
   foreach my $k (keys %ro) {
      if ($ro{$k}{clen} ne $ro{$k}{glen}) {
        print "ERROR: $k $ro{$k}{clen} != $ro{$k}{glen}\n";
        $err++;
      } else {
        print "OK: $k $ro{$k}{clen} == $ro{$k}{glen}\n";
      }
      if ($ro{$k}{cdata} ne $ro{$k}{gdata}) {
        print "ERROR: $k <$ro{$k}{cdata}> != <$ro{$k}{gdata}>\n";
        $err++;
      } else {
        print "OK: $k $ro{$k}{gdata} == $ro{$k}{gdata}\n";
      }
   }
   exit $err;
 }
' working/*.trace

r=$?
if [ $r != 0 ]; then
    estat=$r
fi

end_test
