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

set -e

arg0="$(basename $0)"

builddir=$(pwd)

rm -rf workdir
mkdir workdir
cd workdir

workdir=$(pwd)

ARCH_PQM_CONFIG_FILE="${srcdir}/arch-pqm-tests.conf"

TESTNUM=1 

if test "x" = "x"$TLA; then
  TLA="baz"
fi

if test $TLA = "arx"; then
  INIT="init --no-add"
  DASH_S=
  ID="param id"
  TAG=tag
  IMPORT=commit
  DEFAULT_ARCHIVE="param default-archive"
  REGISTER_ARCHIVE="archives -a"
  MISSING=missing
  ARCH_PQM_CONFIG_FILE="${srcdir}/arch-pqm-tests-arx.conf"
elif test $TLA = "baz"; then
  TLA=baz
  INIT="init-tree --nested"
  DASH_S=
  ID=my-id
  TAG=branch
  IMPORT=import
  DEFAULT_ARCHIVE=my-default-archive
  REGISTER_ARCHIVE=register-archive
  MISSING=whats-missing
else
  TLA=tla
  INIT="init-tree --nested"
  DASH_S=-S
  ID=my-id
  TAG=tag
  IMPORT=import
  DEFAULT_ARCHIVE=my-default-archive
  REGISTER_ARCHIVE=register-archive
  MISSING=whats-missing
fi

if test -z "$TESTS_VERBOSE"; then
    exec 1>/dev/null
fi

verbose () {
  if test -n "$TESTS_VERBOSE"; then
      echo "! $@"
      set -x
  fi
}  

endverbose () {
  if test -n "$TESTS_VERBOSE"; then
      set +x
  fi
}  

clean_workdir () {
  verbose 'cleaning workdir'
  cd "${workdir}/.."
  if test -z "${NO_CLEAN_WORKDIR}"; then
      rm -rf workdir
  else
      mv workdir "workdir.${arg0}"
  fi
  endverbose
}  

arch_pqm () {
  PYTHONPATH=${srcdir}/.. ${srcdir}/../bin/arch-pqm -d -d --queuedir ${builddir}/workdir/pqm --keyring "${srcdir}/.gnupg/pubring.gpg" -c "${ARCH_PQM_CONFIG_FILE}" "$@"
} 

identity_user1() {
  verbose 'changing identity to user1'
  USERID=user1
  ARCHIVEDIR=${workdir}/archivedir-$USERID
  export ARCHIVEDIR
  WORKDIR=${workdir}/workdir-$USERID
  export WORKDIR
  test -d homedir-$USERID || mkdir homedir-$USERID
  HOME=${workdir}/homedir-$USERID
  export HOME
  endverbose
}

identity_user2() {
  verbose 'changing identity to user2'
  USERID=user2
  ARCHIVEDIR=${workdir}/archivedir-$USERID
  export ARCHIVEDIR
  WORKDIR=${workdir}/workdir-$USERID
  export WORKDIR
  test -d homedir-$USERID || mkdir homedir-$USERID
  HOME=${workdir}/homedir-$USERID
  export HOME
  endverbose
}

import_hello_world () {
  revision=$1
  shift
  verbose "! doing hello-world import to $revision"
  mkdir tmp-tree
  cd tmp-tree
  (echo '#include <stdio.h>'; echo '#include <stdlib.h>'; echo 'int main(int argc, char **argv) {';
   echo '  printf("Hello world!");'; echo 'exit (0);'; echo '}') > hello-world.c
  echo 'This is hello-world, 1.0' > README
  $TLA $INIT $revision
  $TLA add hello-world.c README
  $TLA $IMPORT -s 'initial import' 1>/dev/null
  cd ..
  rm -rf tmp-tree
  endverbose
}

initial_setup () {
  verbose 'doing initial setup'
  for user in 1 2; do
      mkdir archivedir-user${user}
      mkdir workdir-user${user}
      mkdir homedir-user${user}
      HOME="${workdir}/homedir-user${user}" $TLA $ID "User ${user} <user$user@example.com>"
  done

  # Patch queue manager dir setup
  mkdir pqm
  HOME=$(pwd)/pqm
  export HOME
  $TLA $ID 'Example Support <support@example.com>'
  $TLA make-archive support@example.com--2003 $(pwd)/pqm-archivedir
  if test "$TLA" = "tla"; then
    $TLA archive-setup support@example.com--2003/hello-world--mainline--1.0
  fi
  import_hello_world support@example.com--2003/hello-world--mainline--1.0
  mkdir tmp-tree
  cd tmp-tree
  $TLA $INIT support@example.com--2003/dists--devel--0
  mkdir configs
  $TLA add configs
  echo "./test support@example.com--2003/hello-world--mainline--1.0" > configs/support
  $TLA add configs/support
  $TLA $IMPORT $DASH_S -s "Initial" 1>/dev/null
  cd ..
  rm -rf tmp-tree

  # User 1 setup
  identity_user1
  $TLA $REGISTER_ARCHIVE $(pwd)/pqm-archivedir
  $TLA make-archive user1@example.com--2003 ${ARCHIVEDIR}/archive
  $TLA $DEFAULT_ARCHIVE user1@example.com--2003
  $TLA $DEFAULT_ARCHIVE
  if test "$TLA" = "tla"; then
    $TLA archive-setup user1@example.com--2003/hello-world--mainline--1.0
  fi
  if test $TLA="arx"; then
    $TLA get support@example.com--2003/hello-world--mainline--1.0 ttmp
    arx fork --dir ttmp user1@example.com--2003/hello-world--mainline--1.0
    arx commit --dir ttmp -s "fork"
    rm -rf ttmp
  else
    $TLA $TAG support@example.com--2003/hello-world--mainline--1.0 user1@example.com--2003/hello-world--mainline--1.0
  fi
  cd ${WORKDIR}
  $TLA get hello-world--mainline--1.0 hello-world >/dev/null 2>&1
  cd -

  # User 2 setup
  identity_user2
  $TLA $REGISTER_ARCHIVE $(pwd)/pqm-archivedir
  $TLA make-archive user2@example.com--2003 ${ARCHIVEDIR}/archive
  $TLA $DEFAULT_ARCHIVE user2@example.com--2003
  $TLA $DEFAULT_ARCHIVE
  if test "$TLA" = "tla"; then
    $TLA archive-setup user2@example.com--2003/hello-world--devo--1.0
  fi
  if test $TLA="arx"; then
    arx get support@example.com--2003/hello-world--mainline--1.0 ttmp
    arx fork --dir ttmp user2@example.com--2003/hello-world--devo--1.0
    arx commit --dir ttmp -s "fork"
    rm -rf ttmp
  else
    $TLA $TAG support@example.com--2003/hello-world--mainline--1.0 user2@example.com--2003/hello-world--devo--1.0
  fi
  cd ${WORKDIR}
  $TLA get hello-world--devo--1.0 hello-world >/dev/null 2>&1
  cd -
  endverbose

  # tell pqm about other archives
  HOME=$(pwd)/pqm
  export HOME
  $TLA $REGISTER_ARCHIVE $(pwd)/archivedir-user1/archive
  $TLA $REGISTER_ARCHIVE $(pwd)/archivedir-user2/archive

  identity_user1
}

initial_setup_with_simple_submission ()
{
  initial_setup
  identity_user1
  verbose 'doing simple submission'
  cd ${WORKDIR}/hello-world
  $TLA mv hello-world.c hello_world.c
  $TLA commit -s 'rename hello-world => hello_world.c'
  echo 'star-merge user1@example.com--2003/hello-world--mainline--1.0 support@example.com--2003/hello-world--mainline--1.0' | submit_merge 'minor rename' "verify"
  endverbose
}

submit_simple_patch ()
{
  identity_user1
  cd ${WORKDIR}/hello-world
  verbose 'submitting simple diff'
  sed -e 's/!/./' < hello-world.c > hello-world.c.new
  (cd .. && diff -u hello-world/hello-world.c hello-world/hello-world.c.new) > ,patch || true
  (echo 'patch support@example.com--2003/hello-world--mainline--1.0'; echo 'fix punctuation'; cat ,patch ) | submit_merge 'fix punctuation' "verify"
  endverbose
}

initial_setup_with_patch_submission ()
{
  initial_setup
  submit_simple_patch
}

submit_merge ()
{
  verbose 'submitting merge'
  subj=$1
  shift
  type=$1
  shift
  if test ${type} = "no-verify"; then
      (echo "From: ${USERID}"; echo "Subject: ${subj}"; echo) | arch_pqm --no-verify --read "$@"
  else
      if test ${type} = "verify"; then
	  tmpf="${WORKDIR}/sig.$$"
	  HOME=${srcdir} gpg --batch --clearsign --passphrase-fd 2 2</dev/null > "${tmpf}"
	  (echo "From: ${USERID}"; echo "Subject: ${subj}"; echo; cat < "${tmpf}") | arch_pqm --read "$@"
	  rm -f "${tmpf}"
      else
	  echo "Unknown verification type ${type}!" 1>&2
	  exit 1
      fi
  fi
  endverbose
}

run_queue ()
{
  verbose 'running queue'
  arch_pqm --run --report "$@" > "${workdir}"/arch-pqm.output
  endverbose
}  

run_queue_xfail ()
{
  run_queue || true
}  

### Utility functions

copy_tree () {
  (cd $1 ; tar cf - .) | (mkdir -p $2 ; cd $2 ; tar xf -)  
}

compare_trees_simple () {
  verbose
  diff -uNr -x ',*' "$@"
  endverbose
}  

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 () {
  verbose
  test -d "$1"
  endverbose
}

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

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

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

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

archive_has_revision_with_summary () {
  archive=$1
  revision=$2
  summary=$3
  verbose "checking for revision \"$1\" in archive \"$2\""

  if test $TLA = "arx"; then
    if test "$summary" = "`arx log --header Summary --remote --branch $archive/$revision`"; then
      echo "Summaries are the same";
    else
      echo "summaries don't match"
      echo "$summary"
      arx log --header Summary --remote --branch $archive/$revision
      arx log --remote --branch support@example.com--2003/hello-world--mainline--1.0
      arx log --remote --branch user1@example.com--2003/hello-world--mainline--1.0
      echo "$archive/$revision"
      exit 1;
    fi
  else
    location=$($TLA whereis-archive "$archive")
    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)
    if test "$TLA" = "tla"; then
      filename="${location}/${category}/${category}--${branch}/${category}--${branch}--${version}/${patchlvl}/log"
    else
      filename="${location}/${category}--${branch}--${version}/${patchlvl}/log"
    fi
    file_exists "${filename}"
    file_matches '^Summary: '"${summary}" "${filename}"
    endverbose
  fi
}

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

changeset_is_null_changeset () {
  cset=$1
  shift
  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
  file=$2
  test -f "${cset}/patches/${file}.patch"
}

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

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

changeset_renames_file () {
  cset=$1
  origfile=$2
  newfile=$3
  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
}
