# vim: set filetype=sh :
#        file: tstlib
#   copyright: Bernd Schumacher <bernd.schumacher@hpe.com> (2007-2020)
#     license: GNU General Public License, version 3
# description: internal test library for shellia
[ -f ia.basic ] && . ./ia.basic || . /usr/share/shellia/ia.basic

LANG=C
ECHO="/bin/echo"

oneline()
{
  awk '{if(NR!=1)printf("\\n");printf("%s",$0,NR)}END{printf("\n")}'
}

# Output with ia.check -C option varies randomly. To check the output, it hast to be sorted.
sort_random_output()
{
  awk 'BEGIN {r=""}
  /^e:/ {print | "sort"; next }
  /^s:/ {print | "sort"; next }
  {close("sort"); print}'
}
#res="$(${ECHO} "line1
#e:1
#s:2
#e:3
#e:5
#s:4
#line2
#e:10
#s:11
#e:15
#s:12
#s:14
#line3" | sort_random_output)"
#exp="line1
#e:1
#e:3
#e:5
#s:2
#s:4
#line2
#e:10
#e:15
#s:11
#s:12
#s:14
#line3"
#[ "$res" = "$exp" ] && ${ECHO} "OK 1" || ${ECHO} "ERROR 1 exp=<$exp> res=<$res>"
#exit 0

# check <comment> [-u <cmd>] [-i <input>] [-s <shell>] <cmd> <expected>
# Description
# If the check fails, the following messag is displayed
help="$(cat <<END
# the following diagnostic output is created (remove with "make clean")
#   exp     contains what is expected
#   res     contains the result that does not match exp
#   res.org Original result before it was uniformed to match exp
#   r4s     the result in the form used in test.* files
END
)"
check()
{
  local input
  local shell
  local unify
  local cmd
  local output
  local comment

  #${ECHO} "DEBUG check: #=<$#> 1=<$1> 2=<$2> 3=<$3> 4=<$4> 5=<$5>" >&2
  comment="$1"
  shift

  input=""
  shell=""
  unify="cat"
  while [ $# -ne 2 ]; do
    if [ "$1" = "-u" ]; then
      unify="$2"
      shift 2
    elif [ "$1" = "-i" ]; then
      input="$2"
      shift 2
    elif [ "$1" = "-s" ]; then
      shell="$2"
      shift 2
    else
      ${ECHO} "ERROR internal error check: unknown option <$1>" >&2
      exit 1
    fi
  done

  cmd="$1"
  [ "$shell" -a -f "$(${ECHO} "$cmd" | awk '{print $1}')" ] && cmd="$shell $cmd"
  [ "$input" ] && cmd="$input | $cmd"

  ${ECHO} "DEBUG check: timeout 60 sh -c \"$cmd\" 2>&1 | eval \"$unify\""
  # make sure also stderr is checked
  #output="$(timeout 60 sh -c "$cmd" 2>&1 | tee res.org | eval "$unify")"
  #timeformat="\n\t%E real,\t%U user,\t%S sys,\t%x exit"
  timeformat="\nreal=%E user=%U sys=%S exit=%x"
  #output="$( { /usr/bin/time -f "$timeformat" timeout 60 sh -c "$cmd" 2>&1 | tee res.org | eval "$unify"; } 2>&1 )"
  #output="$( { /usr/bin/time -f "$timeformat" timeout 60 sh -c "$cmd; ${ECHO}"; } 2>&1 | tee res.org | eval "$unify" )"
  # /usr/bin/time may produce the message "Command exited with non-zero status x"
  output="$( { timeout 60 /usr/bin/time -f "$timeformat" sh -c "$cmd"; } 2>&1 | tee res.org | eval "$unify" )"
  time="$(${ECHO} "$output" | tail -1)"
  output="$(${ECHO} "$output" | head -n -1)"
  #${ECHO} "output=<$output>"
  #${ECHO} "time=<$time>"
  #exit 0
  ${ECHO} "$time $comment \"$cmd\"" | head -1 >>timelist

  ${ECHO}
  if [ "$output" = "$2" ]; then
    ${ECHO} "OK $comment \"$cmd\" => \"$output\"" | oneline
  else
    ${ECHO} "ERROR $comment \"$cmd\" => \"$output\" (expected:\"$2\")" | oneline
    ${ECHO} "$2" | sed -e "s/\\n/
/g" >exp
    ${ECHO} "$output" | sed -e "s/\\n/
/g" >res
    /bin/echo "$output" | ia_easy_backslash |
      sed -e "1 s/^/\"/" | tac | sed -e "1 s/$/\"/" | tac >r4s
    ${ECHO} "The Test result is not what was expected. A Fix is needed."
    ${ECHO} "$help"
    exit 1
  fi
}

set_ia_x()
{
  local traceoff
  traceoff="{ set +x; } 2>/dev/null"
  sed -e "s|^\(\s*ia\>\).*|\1 -x|" -e "s|^\(\s\+\)\(eval \"\$ia_init\".*\)|\1$traceoff\n\1\2|"
}


quote="'"
SED_del_quote_in_trace="-e \"/+\+ /s/${quote}//g\""
SED_del_redirect_in_trace="-e \"/^|*+\+ \([1-9]\|\)>\s*\S\+\s*$/d\""
SED_del_ia_restore_return_in_trace="-e \"/^|*+\+ ia_restore_return$/{N;/\n|*+\+ return/{d}}\""
SED_command_not_found="sed -e \"s/.*: not:\( command\| inaccessible or\|\) not found/: not: not found/\""
UNIFY_mksh="grep -v -e \"^|*+\+ set +x$\" | \
sed -e \"s/+ typeset/+ local/\" \
-e \"s/\(+.*\) \+$/\1/\" \
$SED_del_quote_in_trace \
$SED_del_redirect_in_trace \
$SED_del_ia_restore_return_in_trace \
-e \"/+ ia_save_return/d\" \
-e \"s/^mksh: //\""
UNIFY_bash="sed -e \"s/+\+ /+ /\" \
$SED_del_quote_in_trace"
UNIFY_posh="grep -v -e \"^+ 2> /dev/null $\" | \
sed $SED_del_redirect_in_trace"
UNIFY_mktemp="sed -e \"s/\/tmp\/tmp\.\S\+/\/tmp\/tmp.mktemp/g\""
UNIFY_busybox="sed \
$SED_del_quote_in_trace"

# Use_locallib is needed in hello_world examples.
# To keep them easy, they read /usr/share/shellia/ia* libs.
# This libs will be available after installation of shellia.
use_locallib()
{
  cat $cmd | sed -e "s|^. /usr/share/shellia/ia|. ./ia|" > $cmd.tmp.locallib
  cmd="$cmd.tmp.locallib"
  chmod 755 $cmd
}

# temporary changes to overcome bugs
bug913718_unify()
{
  # bug#913718
  if [ "$shell" = "posh" ]; then
    if [ "$1" ]; then
      eval "$1=\"\$$1 |
sed \\\"s/.tmp.no_set-u//\\\"\""
    else
      ${ECHO} "sed \"s/.tmp.no_set-u//\""
    fi
  fi
}

bug913718_cmd()
{
  # bug#913718
  if [ "$shell" = "posh" ]; then
    cat $cmd | sed "/^set -u/ d" > $cmd.tmp.no_set-u
    cmd="$cmd.tmp.no_set-u"
    chmod 755 $cmd
  fi
}
