#!/bin/bash

# ts 2011.06.27
# Test the correct handling of hardlinks by xorriso options
# -update_r , -hardlinks perform_update , and -extract

export prog=$(basename "$0")

export xorriso=xorriso
export workdir=./releng_generated_data/"$prog"
export image_file="$workdir"/xorriso_hardlinks.iso
export on_disk="$workdir"/xorriso_hardlinks_test_dir
export in_iso=""
export copy_on_disk="$workdir"/xorriso_hardlinks_copy_dir
export keep=0
export failure=0
export simulate_failure=0
export next_is_xorriso=0
export next_is_rc=0
export bad=0
export report_about="-report_about UPDATE"

config_by_var() {
  # This is called once before option interpretation, and once for each
  # option -rc.
  # Variables get set to empty content to keep them from being applied
  # more than once and thus overriding settings of higher precedence.

  test -n "$RELENG_XORRISO" && xorriso="$RELENG_XORRISO" && RELENG_XORRISO=

  test -n "$RELENG_WORKIMAGE" && image_file="$RELENG_WORKIMAGE" \
                              && RELENG_WORKIMAGE=

  test -n "$RELENG_WORKDIR" && on_disk="$RELENG_WORKDIR" && RELENG_WORKDIR=

  test -n "$RELENG_ISODIR" && in_iso="$RELENG_ISODIR" && RELENG_ISODIR=

  test -n "$RELENG_WORKCOPYDIR" && copy_on_disk="$RELENG_WORKCOPYDIR" \
                                && RELENG_WORKCOPYDIR=

}

clean_up() {
  if test "$keep" = 1
  then
    echo "=== Kept test area because of option -keep" >&2
    echo "$on_disk" "$copy_on_disk" "$image_file" "$workdir" >&2
  else
    echo "=== Removing test area" >&2
    rm -r "$on_disk" "$copy_on_disk" "$image_file"
    rm -r "$workdir"
  fi
}


# Setup


# Interpret a default configuration file here, if the test has one.
# This one has none.

# >>> Best would be if the configuration file would not override env variables.

# Process env variables and default configfile variables together
config_by_var


# Now interpret program arguments and possibly given config files
for i in "$@"
do
  if test "$next_is_xorriso" = 1
  then
    xorriso="$i"
    next_is_xorriso=0
  elif test "$next_is_rc" = 1
  then

    # >>> This looks darn dangerous. We need a trustworthy config interpreter.
    # >>> http://www.netjeff.com/humor/item.cgi?file=ShootInFoot-OS
    . "$i"

    config_by_var
    next_is_rc=0
  elif test x"$i" = x"-rc"
  then
    next_is_rc=1
  elif test x"$i" = x"-keep"
  then
    keep=1
  elif test x"$i" = x"-cleanup"
  then
    keep=0
    clean_up
    exit 0
  elif test x"$i" = x"-xorriso"
  then
    next_is_xorriso=1
  elif test x"$i" = x"-v"
  then
    report_about="-report_about ALL"
  elif test x"$i" = x"-fail"
  then
    simulate_failure=1
  else
    echo "Usage: $0 [-rc FILE] [-keep] [-cleanup] [-fail] [-xorriso PATH] [-v]" >&2
    exit 2
  fi
done

test -z "$in_iso" && in_iso="$on_disk"

if test -d ./releng_generated_data
then
  dummy=dummy
else
  echo "=== TEST ENVIRONMENT ERROR: $prog : No ./releng_generated_data directory existing" >&2
  echo "=== Is the current working directory really ./releng of libisoburn ?" >&2
  echo "FAIL : $prog : Test environment error : No ./releng_generated_data directory"
  exit 3
fi
if test -e "$workdir"
then
  echo "=== TEST ENVIRONMENT ERROR: $prog : Existing work directory:" >&2
  ls -ld "$workdir" >&2
  bad=1
fi
if test -e "$image_file"
then
  echo "=== TEST ENVIRONMENT ERROR: $prog : Existing image_file target:" >&2
  ls -ld "$image_file" >&2
  bad=1
fi
if test -e "$on_disk"
then
  echo "=== TEST ENVIRONMENT ERROR: $prog : Existing on_disk target:" >&2
  ls -ld "$on_disk" >&2
  bad=1
fi
if test -e "$copy_on_disk"
then
  echo "=== TEST ENVIRONMENT ERROR: $prog : Existing copy_on_disk target:" >&2
  ls -ld "$copy_on_disk" >&2
  bad=1
fi
if test "$bad" = 1
then
  echo "FAIL : $prog : Test environment error : Existing work files"
  exit 3
fi

bad=0
mkdir "$workdir" || bad=1
mkdir "$on_disk" || bad=1
if test "$bad" = 1
then
  echo "FAIL : $prog : Test environment error : Cannot make directories"
  exit 3
fi


echo "=== Setting up $on_disk with several hardlinks" >&2
echo test_content >"$on_disk"/file_1 || exit 1
echo test_content >"$on_disk"/file_2 || exit 1
ln "$on_disk"/file_1 "$on_disk"/file_1_link_a || exit 1
ln "$on_disk"/file_1 "$on_disk"/file_1_link_b || exit 1
ln "$on_disk"/file_2 "$on_disk"/file_2_link_a || exit 1
ls -l "$on_disk"/*


echo "=== Producing simple image" >&2
"$xorriso" \
  $report_about \
  -version \
  -for_backup \
  -padding 0 \
  -outdev "$image_file" \
  -update_r "$on_disk" "$in_iso" \
  -hardlinks perform_update

echo "=== Copying from image to temporary disk tree" >&2
"$xorriso" \
  $report_about \
  -for_backup \
  -indev "$image_file" \
  -osirrox on \
  -find "$in_iso" -exec lsdl -- \
  -extract "$in_iso" "$copy_on_disk"


if test "$simulate_failure" = 1
then
  echo "===" >&2
  echo "=== SIMULATING FAILURE BY REMOVING AN EXTRACTED FILE" >&2
  echo "===" >&2
  echo "FAIL : $prog : Simulated failure caused by option -fail"
  rm "$copy_on_disk"/file_1_link_b
fi


echo "=== Comparing original disk tree and temporary one" >&2
diff -r "$on_disk" "$copy_on_disk"
if test "$?" -ne 0
then
  echo "=== WRONG: diff -r $on_disk $copy_on_disk   reports differences" >&2
  echo "FAIL : $prog : diff -r reports differences"
  failure=1
else
  echo "=== OK" >&2
fi

echo "=== Checking for hardlinks being siblings" >&2
ls -l "$copy_on_disk"/*
x=$(echo $(ls -l "$copy_on_disk"/* | awk '{print $2}'))
expected="3 3 3 2 2"
if test x"$x" = x"$expected"
then
  echo "=== OK" >&2
else
  echo "=== WRONG: Link count of extracted files is not as expected." >&2
  echo "=== Expected:  $expected" >&2
  echo "=== Got     :  $x" >&2
  echo "FAIL : $prog : Link count of extracted files is not as expected."
  failure=1
fi


clean_up


# Report result
echo 
if test "$failure" = 1
then
  echo "======== $prog :" 'FAILED'
  echo 
  exit 1
else
  echo "======== $prog :" "Passed"
  echo 
fi

exit 0