# -*- mode: sh; coding: utf-8 -*-
# Various functions for tla testsuite 
# Copyright © 2003 Colin Walters <walters@verbum.org>
#
# See the file "COPYING" for further information about
# the copyright and warranty status of this work.

set -e

builddir=$(pwd)

DEBUGPREFIX=
#DEBUGPREFIX='valgrind -q --db-attach=yes'

TESTNUM=1

verbose () {
  if test -n "$TESTS_VERBOSE"; then
    echo "$@" >&2
  fi
}  

verbosecmd () {
  if test -n "$TESTS_VERBOSE"; then
    echo "=>" "$@" >&2
  fi
}

tla () {
  verbosecmd "${builddir}/../baz/baz" "$@"
  $DEBUGPREFIX ${builddir}/../baz/baz "$@"
}

test_class () {
  echo ""
  echo "======= TESTING: $@ =======" >&2
  if test -z "$TESTS_VERBOSE"; then
    exec 1>/dev/null
  fi
}  

begin_test_savectx () {
  echo "Test $TESTNUM: $@" >&2
}  

begin_test () {
  begin_test_savectx "$@"
  _begin_test_dir="$(pwd)"
  mkdir test-$TESTNUM-workdir
  cd test-$TESTNUM-workdir
}  

end_test_savectx () {
  echo "Test $TESTNUM: PASS" >&2
  TESTNUM=$(($TESTNUM + 1))
}

end_test () {
  end_test_savectx "$@"
  cd "${_begin_test_dir}"
  rm -rf test-$TESTNUM-workdir
  rm -rf $(cat $HOME/.arch-params/=arch-cache)
}  

test_fail () {
  # Failures display error message and exit
  # usage: test_fail "where: why"
  echo "Test $TESTNUM: FAILED: $@" >&2
  exit 1
}

# Is there a portable way to do this?
# trap "test_fail" ERR 

clean_workdir () {
  verbose '! cleaning workdir'
  rm -rf archivedir
  rm -rf workdir
  rm -rf homedir
}  

setup_workdir () {
  clean_workdir
  verbose '! setting up workdir'
  mkdir archivedir
  ARCHIVEDIR=$(pwd)/archivedir
  export ARCHIVEDIR
  CACHEDARCHIVEDIR=cached:$(pwd)/archivedir
  export CACHEDARCHIVEDIR
  mkdir workdir
  WORKDIR=$(pwd)/workdir
  export WORKDIR
  mkdir homedir
  HOME=$(pwd)/homedir  # we do this so we don't mess with the user's archives
  export HOME
  mkdir $HOME/.arch-params
  echo $(pwd)/cache > $HOME/.arch-params/=arch-cache
  rm -Rf $(pwd)/cache
  cd workdir
  cd $(if test -x /bin/pwd; then /bin/pwd; else pwd; fi)  # canonicalize
}

dir_exists()
{
  if test -d $1; then
    return 0
  else echo $1 does not exist >&2
    return 1
  fi
}

initial_setup () {
  setup_workdir
  verbose '! doing initial setup'
  tla my-id 'Jane Doe <jane@example.com>'
}  

setup_with_empty_archives () {
  initial_setup
  verbose '! creating empty archives'
  tla make-archive jane@example.com--2003 ${CACHEDARCHIVEDIR}/jane-archive
  tla make-archive foo@example.org--2003 ${CACHEDARCHIVEDIR}/foo-archive
}

setup_with_empty_tla_archives () {
  initial_setup
  verbose '! creating empty archives'
  tla make-archive --tla jane@example.com--2003 ${ARCHIVEDIR}/jane-archive
  tla make-archive --tla foo@example.org--2003 ${ARCHIVEDIR}/foo-archive
}

setup_with_setup_archives () {
  initial_setup
  verbose '! creating and setting up archives'
  tla make-archive jane@example.com--2003 ${CACHEDARCHIVEDIR}/jane-archive 1>/dev/null
  tla make-archive foo@example.org--2003 ${CACHEDARCHIVEDIR}/foo-archive 1>/dev/null
}

setup_with_setup_tla_archives () {
  initial_setup
  verbose '! creating and setting up archives'
  tla make-archive --tla jane@example.com--2003 ${CACHEDARCHIVEDIR}/jane-archive 1>/dev/null
  tla make-archive --tla foo@example.org--2003 ${CACHEDARCHIVEDIR}/foo-archive 1>/dev/null
}

make_hello_world () {
  dir=$1
  shift
  mkdir "$dir"
  (echo '#include <stdio.h>'; echo '#include <stdlib.h>'; echo 'int main(int argc, char **argv) {';
   echo '  printf("Hello world!");'; echo 'exit (0);'; echo '}') > "${dir}"/hello-world.c
  echo 'This is hello-world, 1.0' > "${dir}"/README
}  

setup_with_trivial_archives () {
  tagging_method=$1
  if test -z "${tagging_method}"; then
    tagging_method=explicit
  fi
  setup_with_setup_archives
  verbose '! doing initial imports'
  make_hello_world tmp-tree
  cd tmp-tree
  tla init-tree --nested jane@example.com--2003/hello-world--mainline--1.0
  tla id-tagging-method "${tagging_method}" 1>/dev/null
  tla add hello-world.c README
  tla import -L 'initial import' 1>/dev/null
  cd ..
  rm -rf tmp-tree
}

setup_with_trivial_tla_archives () {
  tagging_method=$1
  if test -z "${tagging_method}"; then
    tagging_method=explicit
  fi
  setup_with_setup_tla_archives
  verbose '! doing initial imports'
  make_hello_world tmp-tree
  cd tmp-tree
  tla init-tree --nested jane@example.com--2003/hello-world--mainline--1.0
  tla id-tagging-method "${tagging_method}" 1>/dev/null
  tla add hello-world.c README
  tla import -L 'initial import' 1>/dev/null
  cd ..
  rm -rf tmp-tree
}

setup_with_somewhat_interesting_explicit_archives () {
  setup_with_setup_archives

  verbose '! doing initial imports'
  make_hello_world tmp-tree
  cd tmp-tree

  tla init-tree --nested jane@example.com--2003/hello-world--mainline--1.0
  tla id-tagging-method explicit 1>/dev/null

  mkdir new_directory old_directory
  ln -s old_directory link_to_old_directory
  ln -s new_directory link_to_new_directory

  cp hello-world.c goodbye-world.c
  ln -s README link_to_README
  ln -s hello-world.c link_to_hello-world.c
  ln -s goodbye-world.c link_to_goodbye-world.c

  mkdir -p hierarchy
  mkdir -p hierarchy/left/left hierarchy/left/right
  mkdir -p hierarchy/right/left hierarchy/right/right
  tla add $(find hierarchy -type d)

  tla add new_directory old_directory link_to_old_directory link_to_new_directory
  tla add hello-world.c goodbye-world.c link_to_hello-world.c link_to_goodbye-world.c README link_to_README 
  tla import -L 'initial import' 1>/dev/null

  cd ..
  rm -rf tmp-tree
}

setup_with_somewhat_interesting_explicit_tla_archives () {
  setup_with_setup_tla_archives

  verbose '! doing initial imports'
  make_hello_world tmp-tree
  cd tmp-tree

  tla init-tree --nested jane@example.com--2003/hello-world--mainline--1.0
  tla id-tagging-method explicit 1>/dev/null

  mkdir new_directory old_directory
  ln -s old_directory link_to_old_directory
  ln -s new_directory link_to_new_directory

  cp hello-world.c goodbye-world.c
  ln -s README link_to_README
  ln -s hello-world.c link_to_hello-world.c
  ln -s goodbye-world.c link_to_goodbye-world.c

  mkdir -p hierarchy
  mkdir -p hierarchy/left/left hierarchy/left/right
  mkdir -p hierarchy/right/left hierarchy/right/right
  tla add $(find hierarchy -type d)

  tla add new_directory old_directory link_to_old_directory link_to_new_directory
  tla add hello-world.c goodbye-world.c link_to_hello-world.c link_to_goodbye-world.c README link_to_README 
  tla import -L 'initial import' 1>/dev/null

  cd ..
  rm -rf tmp-tree
}

### Utility functions

copy_tree () {
  tar_prog=$("$srcroot/build-tools/scripts/option" gnu-tar)
  export $tar_prog
  (cd $1 ; "$tar_prog" cf - .) | (mkdir -p $2 ; cd $2 ; "$tar_prog" xf -)  
}

compare_trees_simple () {
  verbosecmd 'diff -uNr -x ,* -x +*' "$@"
  diff -uNr -x ',*' -x '+*' "$@"
}  

assert_trees_equal () {
  output=",what-changed-$$"
  tla mkpatch "$1" "$2" "${output}"
  changeset_is_null_changeset "${output}"
}  

assert_working_tree_equivalence () {
  diff -uNr -x ',*' -x '{arch}' "$@"
}  

dir_exists () {
  verbosecmd test -d "$1"
  test -d "$1"
}

file_exists () {
  verbosecmd test -f "$1"
  test -f "$1"
}  

file_is_empty () {
  f=$1
  shift
  verbosecmd "test -f $f && test ! -s $f"
  test -f "$f" && test ! -s "$f"
}  

dir_is_empty () {
  d=$1
  shift
  verbosecmd 'test -z $(ls ' "$d"')'
  test -z "$(ls "$d")"
}

file_matches () {
  verbosecmd egrep "$1" "$2"
  egrep "$1" "$2" 1>/dev/null
}

archive_has_revision_with_summary () {
  archive=$1
  revision=$2
  summary=$3
  location=$(tla whereis-archive "$archive"|sed s/cached://)
  category=$(tla parse-package-name -c $revision)
  branch=$(tla parse-package-name -b $revision)
  version=$(tla parse-package-name -v $revision)
  patchlvl=$(tla parse-package-name -l $revision)
  filename="${location}/${category}--${branch}--${version}/${patchlvl}/log"
  file_exists "${filename}"
  file_matches '^Summary: '"${summary}" "${filename}"
}

missing_patches_are () {
  archive=$1
  shift
  tla missing "${archive}" >,missing
  for patch in "$@"; do
    sed -e "/$patch/d" <,missing >,missing.new
    mv ,missing.new ,missing
  done
  file_is_empty ,missing
}  

changeset_is_null_changeset () {
  cset=$1
  shift
  verbose "testing for null changeset $cset"
  file_is_empty "${cset}/mod-dirs-index"
  file_is_empty "${cset}/mod-files-index"
  file_is_empty "${cset}/modified-only-dir-metadata"
  dir_is_empty  "${cset}/new-files-archive"
  file_is_empty "${cset}/modified-only-dir-metadata"
  dir_is_empty  "${cset}/patches"
  dir_is_empty  "${cset}/removed-files-archive"
}

changeset_patches_file () {
  cset=$1
  shift
  file=$1
  shift
  verbosecmd "${cset}/patches/${file}.patch"
  test -f "${cset}/patches/${file}.patch"
}

changeset_adds_file () {
  cset=$1
  shift
  file=$1
  shift
  verbosecmd test -f "${cset}/new-files-archive/${file}"
  test -f "${cset}/new-files-archive/${file}"
}

changeset_deletes_file () {
  cset=$1
  shift
  file=$1
  shift
  verbosecmd test -f "${cset}/removed-files-archive/${file}"
  test -f "${cset}/removed-files-archive/${file}"
}

changeset_renames_file () {
  cset=$1
  shift
  origfile=$1
  shift
  newfile=$1
  shift
  verbosecmd egrep "^${origfile}" "${cset}/orig-files-index"
  egrep "^\./${origfile}" "${cset}/orig-files-index" 1>/dev/null
  verbosecmd egrep "^${newfile}" "${cset}/mod-files-index"
  egrep "^\./${newfile}" "${cset}/mod-files-index" 1>/dev/null
}

# tag: Colin Walters Tue, 16 Sep 2003 20:48:33 -0400 (test-framework.sh)
#
