#!/bin/bash

cvmfs_test_name="History"
cvmfs_test_autofs_on_startup=false
cvmfs_test_suites="quick"

produce_files_in() {
	local working_dir=$1

	pushdir $working_dir

  touch gedicht
  echo "Ein Vater an seinen Sohn"                         >> gedicht
  echo ""                                                 >> gedicht
  echo "Wie die Himmelslüfte mit den Rosen"               >> gedicht
  echo "An den Frühlingsmorgen zärtlich kosen,"           >> gedicht
  echo "Kind, so schmeichelt dir"                         >> gedicht
  echo "Itzt das äußre Glück in deinen Jugendtagen."      >> gedicht
  echo "Tränen sahst du nur, noch rangen keine Klagen"    >> gedicht
  echo "Sich aus deiner Brust herfür."                    >> gedicht
  echo ""                                                 >> gedicht
  echo "Aber sieh! der Hain, der kaum entzücket,"         >> gedicht
  echo "Neigt sich, plötzlich rast der Sturm, zerknicket" >> gedicht
  echo "Liegt die Rosenblum!"                             >> gedicht
  echo "O so ist es, Sohn, mit unsern Sinnesfreuden,"     >> gedicht
  echo "Unserm Golde, unsern lichten Herrlichkeiten,"     >> gedicht
  echo "So mit unserm Flitterruhm."                       >> gedicht
  echo ""                                                 >> gedicht
  echo "Nur des Höchsten Abglanz, der Gerechte,"          >> gedicht
  echo "Welcher in dem schröcklichen Gefechte"            >> gedicht
  echo "Zwischen Lust und Pflicht"                        >> gedicht
  echo "Jener sich entringt, der höhern Weisheit Stimme"  >> gedicht
  echo "Folget, trotz der Selbstsucht heißem Grimme,"     >> gedicht
  echo "Die sein Herz mit Schwertern sticht –"            >> gedicht
  echo ""                                                 >> gedicht
  echo "Dessen Wollust trägt von hier die Bahre"          >> gedicht
  echo "Nicht, es löscht sie nicht der Strom der Jahre,"  >> gedicht
  echo "Nicht die Ewigkeit:"                              >> gedicht
  echo "Angeleuchtet könnt er in den letzten Blitzen"     >> gedicht
  echo "Und vom Weltenumsturz angeschwungen sitzen"       >> gedicht
  echo "Ohne Menschenbangigkeit."                         >> gedicht
  echo ""                                                 >> gedicht
  echo "       Friedrich Schiller"                        >> gedicht

  mkdir -p dir1/dir1/dir1
  mkdir -p dir1/dir2/dir1
  mkdir -p dir1/dir3/dir1
  mkdir -p dir2/dir1

  ln gedicht schiller
  ln -s gedicht symbolic_schiller

  touch dir1/dir1/heine
  echo "An die Jungen"                                >> dir1/dir1/heine
  echo ""                                             >> dir1/dir1/heine
  echo "Laß dich nicht kirren, laß dich nicht wirren" >> dir1/dir1/heine
  echo "Durch goldne Äpfel in deinem Lauf!"           >> dir1/dir1/heine
  echo "Die Schwerter klirren, die Pfeile schwirren," >> dir1/dir1/heine
  echo "Doch halten sie nicht den Helden auf."        >> dir1/dir1/heine
  echo ""                                             >> dir1/dir1/heine
  echo "Ein kühnes Beginnen ist halbes Gewinnen,"     >> dir1/dir1/heine
  echo "Ein Alexander erbeutet die Welt!"             >> dir1/dir1/heine
  echo "Kein langes Besinnen! Die Königinnen"         >> dir1/dir1/heine
  echo "Erwarten schon knieend den Sieger im Zelt."   >> dir1/dir1/heine
  echo ""                                             >> dir1/dir1/heine
  echo "Wir wagen, wir werben! besteigen als Erben"   >> dir1/dir1/heine
  echo "Des alten Darius Bett und Thron."             >> dir1/dir1/heine
  echo "O süßes Verderben! o blühendes Sterben!"      >> dir1/dir1/heine
  echo "Berauschter Triumphtod zu Babylon!"           >> dir1/dir1/heine
  echo ""                                             >> dir1/dir1/heine
  echo "       Heinrich Heine"                        >> dir1/dir1/heine
  touch dir1/.cvmfscatalog

	popdir
}

change_files_1_in() {
  local working_dir=$1

  pushdir $working_dir

  touch dir2/morgenstern
  echo "Die Irrlichter"                            >> dir2/morgenstern
  echo ""                                          >> dir2/morgenstern
  echo "Ein Irrlicht, schwebt' ich heut im Traume" >> dir2/morgenstern
  echo "auf einem weiten, düstren Sumpfe,"         >> dir2/morgenstern
  echo "und um mich der Gespielen Reigen"          >> dir2/morgenstern
  echo "in wunderlich geschlungnen Kränzen."       >> dir2/morgenstern
  echo "Wir sangen traurig-süße Lieder"            >> dir2/morgenstern
  echo "mit leisen, feinen Geisterstimmen,"        >> dir2/morgenstern
  echo "viel feiner als die lauten Grillen,"       >> dir2/morgenstern
  echo "die fern im Korn eintönig sangen."         >> dir2/morgenstern
  echo "Wir sangen, wie das harte Schicksal"       >> dir2/morgenstern
  echo "uns wehre, daß wir Menschen würden:"       >> dir2/morgenstern
  echo "So oft schon waren wir erschienen,"        >> dir2/morgenstern
  echo "wo sich zwei Liebende vereinten,"          >> dir2/morgenstern
  echo "doch immer, ach, war schon ein andres"     >> dir2/morgenstern
  echo "Irr-Seelchen uns zuvorgekommen,"           >> dir2/morgenstern
  echo "und seufzend hatten wir von Neuem"         >> dir2/morgenstern
  echo "zurück gemußt zum dunklen Sumpfe."         >> dir2/morgenstern
  echo "So sangen wir von unsern Leiden -"         >> dir2/morgenstern
  echo "als uns mit einem Mal Entsetzen"           >> dir2/morgenstern
  echo "in wirren Läufen huschen machte."          >> dir2/morgenstern
  echo "Ein Mensch entsprang dem nahen Walde"      >> dir2/morgenstern
  echo "und lief verzweifelten Gebahrens"          >> dir2/morgenstern
  echo "gerade auf uns zu -: Der Boden"            >> dir2/morgenstern
  echo "schlug schwankend, eine schwere Woge,"     >> dir2/morgenstern
  echo "dem Armen überm Haupt zusammen."           >> dir2/morgenstern
  echo "Verstummt zu zitterndem Geflüster"         >> dir2/morgenstern
  echo "umschwirrten wir die grause Stelle ..."    >> dir2/morgenstern
  echo "Bald aber sangen wir von neuem"            >> dir2/morgenstern
  echo "die alten traurig-süßen Lieder."           >> dir2/morgenstern
  echo ""                                          >> dir2/morgenstern
  echo "      Christian Morgenstern"               >> dir2/morgenstern

  rm dir1/dir1/heine
  ln -s dir2/morgenstern christian

  popdir
}

change_files_2_in() {
  local working_dir=$1

  pushdir $working_dir

  rm -fR dir1

  popdir
}

change_files_3_in() {
  local working_dir=$1

  pushdir $working_dir

  rm -f dir2/morgenstern
  rm christian
  echo "not here anymore" > christian

  popdir
}

change_files_4_in() {
  local working_dir=$1

  pushdir $working_dir
  rm -fR ${working_dir}/*
  popdir
}

cvmfs_run_test() {
  logfile=$1
  local repo_dir=/cvmfs/$CVMFS_TEST_REPO

  local scratch_dir=$(pwd)
  mkdir reference_dir1
  mkdir reference_dir2
  mkdir reference_dir3
  mkdir reference_dir4
  mkdir reference_dir5
  local reference_dir1=$scratch_dir/reference_dir1
  local reference_dir2=$scratch_dir/reference_dir2
  local reference_dir3=$scratch_dir/reference_dir3
  local reference_dir4=$scratch_dir/reference_dir4
  local reference_dir5=$scratch_dir/reference_dir5

  local first_tag="initial"
  local first_tag_desc="initial-tag"
  local second_tag="intermediate"
  local second_tag_desc="intermediate-revision"
  local third_tag="third_tag"
  local third_tag_desc="last-tag-revision with spaces!"
  local trunk_tag="trunk"
  local prev_trunk_tag="trunk-previous"

  echo "*** {0} create a fresh repository named $CVMFS_TEST_REPO with user $CVMFS_TEST_USER"
  create_empty_repo $CVMFS_TEST_REPO $CVMFS_TEST_USER || return $?

  # ============================================================================

  echo "*** {1} starting transaction to edit repository"
  start_transaction $CVMFS_TEST_REPO || return $?

  echo "*** {1} putting some stuff in the new repository"
  produce_files_in $repo_dir || return 3

  echo "*** {1} putting exactly the same stuff in the scratch spaces for comparison"
  produce_files_in $reference_dir1 || return 4
  produce_files_in $reference_dir2 || return 4
  produce_files_in $reference_dir3 || return 4
  produce_files_in $reference_dir4 || return 4
  produce_files_in $reference_dir5 || return 4

  echo "*** {1} creating CVMFS snapshot"
  publish_repo $CVMFS_TEST_REPO -a $first_tag -m "$first_tag_desc" || return $?

  echo "*** {1} compare the results of cvmfs to our reference copy"
  compare_directories $repo_dir $reference_dir1 $CVMFS_TEST_REPO || return $?

  # ============================================================================

  echo "*** {2} init a new transaction to change something in repository $CVMFS_TEST_REPO (1/2)"
  start_transaction $CVMFS_TEST_REPO || return $?

  echo "*** {2} change stuff in the repository (1/2)"
  change_files_1_in $repo_dir || return 7

  echo "*** {2} change exactly the same stuff in the scratch spaces (1/2)"
  change_files_1_in $reference_dir2 || return 8
  change_files_1_in $reference_dir3 || return 8
  change_files_1_in $reference_dir4 || return 8
  change_files_1_in $reference_dir5 || return 8

  echo "*** {2} creating CVMFS snapshot (1/2)"
  publish_repo $CVMFS_TEST_REPO -a $second_tag -m "$second_tag_desc" || return $?

  echo "*** {2} compare the changed directories (1/2)"
  compare_directories $repo_dir $reference_dir2 $CVMFS_TEST_REPO || return $?

  # ============================================================================

  echo "*** {3} init a new transaction to change something in repository $CVMFS_TEST_REPO (2/2)"
  start_transaction $CVMFS_TEST_REPO || return $?

  echo "*** {3} change stuff in the repository (2/2)"
  change_files_2_in $repo_dir || return 7

  echo "*** {3} change exactly the same stuff in the scratch space (2/2)"
  change_files_2_in $reference_dir3 || return 8

  echo "*** {3} creating CVMFS snapshot (2/2)"
  publish_repo $CVMFS_TEST_REPO -a $third_tag -m "$third_tag_desc" || return $?

  echo "*** {3} compare the changed directories (2/2)"
  compare_directories $repo_dir $reference_dir3 $CVMFS_TEST_REPO || return $?

  # ============================================================================

  echo "*** {4} check catalog and data integrity"
  check_repository $CVMFS_TEST_REPO -i || return $?

  echo "*** {4} current tag statistics:"
  cvmfs_server tag -l $CVMFS_TEST_REPO

  echo "*** {4} check tag descriptions"
  if cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$first_tag"       && \
     cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$first_tag_desc"  && \
     cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$second_tag"      && \
     cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$second_tag_desc" && \
     cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$third_tag"       && \
     cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$third_tag_desc"  && \
     cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$trunk_tag"       && \
     cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag"; then
    echo "*** {4} all tags and their descriptions found"
  else
    return 9
  fi

  # ============================================================================

  echo "*** {5} rollback to second tagged revision: $second_tag"
  cvmfs_server rollback -f -t $second_tag $CVMFS_TEST_REPO || return $?

  echo "*** {5} compare to reference directory"
  compare_directories $repo_dir $reference_dir2 $CVMFS_TEST_REPO || return 10

  echo "*** {5} check catalog and data integrity"
  check_repository $CVMFS_TEST_REPO -i || return $?

  echo "*** {5} current tag statistics:"
  cvmfs_server tag -l $CVMFS_TEST_REPO

  echo "*** {5} check tag descriptions"
  if cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$first_tag"       && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$first_tag_desc"  && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$second_tag"      && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$second_tag_desc" && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$trunk_tag"; then
    echo "*** {5} all tags and their descriptions found"
  else
    return 11
  fi
  if [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag"      | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$prev_trunk_tag" | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag_desc" | wc -l) -ne 0 ]; then
    return 12
  fi

  # ============================================================================

  echo "*** {6} init a new transaction to change something in repository $CVMFS_TEST_REPO"
  start_transaction $CVMFS_TEST_REPO || return $?

  echo "*** {6} change stuff in the repository"
  change_files_3_in $repo_dir || return 13

  echo "*** {6} change exactly the same stuff in the scratch space"
  change_files_3_in $reference_dir4 || return 14

  echo "*** {6} creating CVMFS snapshot"
  publish_repo $CVMFS_TEST_REPO || return $?

  echo "*** {6} compare the changed directories"
  compare_directories $repo_dir $reference_dir4 $CVMFS_TEST_REPO || return $?

  echo "*** {6} current tag statistics:"
  cvmfs_server tag -l $CVMFS_TEST_REPO

  echo "*** {6} check tag descriptions"
  if cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$first_tag"       && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$first_tag_desc"  && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$second_tag"      && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$second_tag_desc" && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$trunk_tag"       && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag"; then
    echo "*** {6} all tags and their descriptions found"
  else
    return 15
  fi
  if [ $(cvmfs_server tag -l $CVMFS_TEST_REPO | grep "$third_tag_desc" | wc -l) -ne 0 ]; then
    return 16
  fi

  # ============================================================================

  echo "*** {7} rollback to first tagged revision: $first_tag"
  cvmfs_server rollback -f -t $first_tag $CVMFS_TEST_REPO || return $?

  echo "*** {7} compare to reference directory"
  compare_directories $repo_dir $reference_dir1 $CVMFS_TEST_REPO || return 17

  echo "*** {7} check catalog and data integrity"
  check_repository $CVMFS_TEST_REPO -i || return $?

  echo "*** {7} current tag statistics:"
  cvmfs_server tag -l $CVMFS_TEST_REPO

  echo "*** {7} check tag descriptions"
  if cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$first_tag"      && \
     cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$first_tag_desc" && \
     cvmfs_server tag -l $CVMFS_TEST_REPO    | grep -q "$trunk_tag"; then
    echo "*** {7} all tags and their descriptions found"
  else
    return 18
  fi
  if [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag"      | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag_desc" | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag"       | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag_desc"  | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$prev_trunk_tag"  | wc -l) -ne 0 ]; then
    return 19
  fi

  # ============================================================================

  echo "*** {8} create a couple of revisions..."
  local iterations=5
  while [ $iterations -gt 0 ]; do
    echo "*** {8} init a new transaction in $CVMFS_TEST_REPO"
    start_transaction $CVMFS_TEST_REPO || return $?

    echo "*** {8} creating CVMFS snapshot"
    publish_repo $CVMFS_TEST_REPO || return $?

    iterations=$(( $iterations - 1))
  done

  echo "*** {8} check catalog and data integrity"
  check_repository $CVMFS_TEST_REPO -i || return $?

  # ============================================================================

  local newest_hash=$(sudo cvmfs_server tag -l -x $CVMFS_TEST_REPO | head -n1 | awk '{print $2}')

  echo "*** {9} moving tag '$first_tag' to hash '$newest_hash'"
  cvmfs_server tag -a $first_tag -h $newest_hash -m "$first_tag_desc+1" $CVMFS_TEST_REPO || return $?

  echo "*** {9} compare to reference directory"
  compare_directories $repo_dir $reference_dir1 $CVMFS_TEST_REPO || return 20

  echo "*** {9} check catalog and data integrity"
  check_repository $CVMFS_TEST_REPO -i || return $?

  echo "*** {9} current tag statistics:"
  cvmfs_server tag -l $CVMFS_TEST_REPO

  echo "*** {9} check tag descriptions"
  if cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$first_tag"        && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$first_tag_desc+1" && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$trunk_tag"        && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag"; then
    echo "*** {9} all tags and their descriptions found"
  else
    return 21
  fi
  if [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag"      | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag_desc" | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag"       | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag_desc"  | wc -l) -ne 0 ]; then
    return 22
  fi

  # ============================================================================

  echo "*** {10} remove tag '$first_tag'"
  cvmfs_server tag -r $first_tag -f $CVMFS_TEST_REPO || return 23

  echo "*** {10} current tag statistics:"
  cvmfs_server tag -l $CVMFS_TEST_REPO

  echo "*** {10} check tag existence"
  if cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$trunk_tag"        && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag"; then
    echo "*** {10} all tags and their descriptions found"
  else
    return 24
  fi
  if [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$first_tag"       | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$first_tag_desc"  | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag"      | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag_desc" | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag"       | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag_desc"  | wc -l) -ne 0 ]; then
    return 25
  fi

  # ============================================================================

  echo "*** {11} create a new revision to be able to roll back to something"
  start_transaction $CVMFS_TEST_REPO || return $?

  echo "*** {11} deleting everything in the repository"
  change_files_4_in $repo_dir || return 26

  echo "*** {11} change exactly the same stuff in the scratch space"
  change_files_4_in $reference_dir5 || return 27

  echo "*** {11} creating CVMFS snapshot"
  publish_repo $CVMFS_TEST_REPO || return $?

  echo "*** {11} compare to reference directory"
  compare_directories $repo_dir $reference_dir5 $CVMFS_TEST_REPO || return 28

  echo "*** {11} check catalog and data integrity"
  check_repository $CVMFS_TEST_REPO -i || return $?

  echo "*** {11} current tag statistics:"
  cvmfs_server tag -l $CVMFS_TEST_REPO

  echo "*** {11} check tag existence (especially $prev_trunk_tag)"
  if cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$trunk_tag"        && \
     cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag"; then
    echo "all tags and their descriptions found"
  else
    return 29
  fi
  if [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$first_tag"       | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$first_tag_desc"  | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag"      | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag_desc" | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag"       | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag_desc"  | wc -l) -ne 0 ]; then
    return 30
  fi

  echo "*** {11} initiate a rollback"
  cvmfs_server rollback -f $CVMFS_TEST_REPO || return 31

  echo "*** {11} compare to reference directory"
  compare_directories $repo_dir $reference_dir1 $CVMFS_TEST_REPO || return 32

  echo "*** {11} check catalog and data integrity"
  check_repository $CVMFS_TEST_REPO -i || return $?

  echo "*** {11} current tag statistics:"
  cvmfs_server tag -l $CVMFS_TEST_REPO

  echo "*** {11} check tag existence (especially $prev_trunk_tag)"
  if cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$trunk_tag"; then
    echo "*** {11} all tags and their descriptions found"
  else
    return 33
  fi
  if [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$first_tag"       | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$first_tag_desc"  | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag"      | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$second_tag_desc" | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag"       | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$third_tag_desc"  | wc -l) -ne 0 ] || \
     [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep "$prev_trunk_tag"  | wc -l) -ne 0 ]; then
    return 34
  fi

  # ============================================================================

  echo "*** {12} initiate a rollback (should fail)"
  cvmfs_server rollback -f $CVMFS_TEST_REPO && return 35

  # ============================================================================

  echo "*** {13} open transaction to see if tag removal fails in transaction"
  start_transaction $CVMFS_TEST_REPO || return $?

  local oldest_tag="$(sudo cvmfs_server tag -l -x $CVMFS_TEST_REPO | tail -n1 | awk '{print $1}')"
  echo "*** {13} trying to remove $oldest_tag (should fail)"
  cvmfs_server tag -r $oldest_tag -f $CVMFS_TEST_REPO  && return 37

  echo "*** {13} check if tag is still there"
  cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$oldest_tag" || return 38

  echo "*** {13} abort transaction"
  cvmfs_server abort -f $CVMFS_TEST_REPO || return 39

  # ============================================================================

  local oldest_tags="$(sudo cvmfs_server tag -l -x $CVMFS_TEST_REPO | tail -n3 | awk '{print $1}')"
  local remove_flags=""
  local oldest_tags_list=""
  for tag in $oldest_tags; do
    remove_flags="-r $tag $remove_flags"
    oldest_tags_list="$tag $oldest_tags_list"
  done
  echo "*** {14} removing multiple tags ($oldest_tags_list)"
  cvmfs_server tag $remove_flags -f $CVMFS_TEST_REPO || return 40

  echo "*** {14} check that trunk is still there"
  cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$trunk_tag" || return 41

  echo "*** {14} check that the tags ($oldest_tags_list) are gone"
  for tag in $oldest_tags; do
    cvmfs_server tag -l $CVMFS_TEST_REPO | grep -q "$tag" && return 42
  done

  echo "*** {14} check the number of tags"
  [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | wc -l) -eq 5 ] || return 43

  # ============================================================================

  echo "*** {15} create a new revision to have an undo point"
  start_transaction $CVMFS_TEST_REPO || return $?
  publish_repo $CVMFS_TEST_REPO      || return 44

  echo "*** {15} check if trunk-previous is there"
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag" || return 45

  # ============================================================================

  echo "*** {16} open transaction to see if rollback fails in transaction"
  start_transaction $CVMFS_TEST_REPO || return $?

  echo "*** {16} try to rollback (should fail)"
  cvmfs_server rollback -f $CVMFS_TEST_REPO && return 46

  echo "*** {16} check if tag is still there"
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag" || return 47

  echo "*** {16} abort transaction"
  cvmfs_server abort -f $CVMFS_TEST_REPO || return 48

  # ============================================================================

  echo "*** {17} delete all auto tags"
  local auto_tags="$(cvmfs_server tag -lx $CVMFS_TEST_REPO | grep '^generic' | awk '{print $1}')"
  remove_flags=""
  for tag in $auto_tags; do
    remove_flags="-r $tag $remove_flags"
  done
  cvmfs_server tag $remove_flags -f $CVMFS_TEST_REPO || return 49

  echo "*** {17} check if trunk and trunk-previous are there"
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$trunk_tag"      || return 50
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag" || return 50

  echo "*** {17} check the number of tags"
  [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | wc -l) -eq 2 ] || return 51

  # ============================================================================

  echo "*** {18} disable auto tagging"
  local conf_file="/etc/cvmfs/repositories.d/${CVMFS_TEST_REPO}/server.conf"
  cat $conf_file | sed 's/^\(CVMFS_AUTO_TAG=\).*$/\1false/' | tee server.conf || return 52
  sudo cp server.conf $conf_file || return 53

  echo "*** {18} get revision of current trunk tag"
  local trunk_revision_1="$(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep '^trunk ' | awk '{print $4}')"

  echo "*** {18} create a couple of revisions..."
  iterations=5
  while [ $iterations -gt 0 ]; do
    echo "*** {18} init a new transaction in $CVMFS_TEST_REPO"
    start_transaction $CVMFS_TEST_REPO || return $?

    echo "*** {18} creating CVMFS snapshot"
    publish_repo $CVMFS_TEST_REPO || return $?

    iterations=$(( $iterations - 1))
  done

  echo "*** {18} check if trunk and trunk-previous are there"
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$trunk_tag"      || return 54
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag" || return 54

  echo "*** {18} check the number of tags"
  [ $(cvmfs_server tag -l -x $CVMFS_TEST_REPO | wc -l) -eq 2 ] || return 55

  echo "*** {18} get revision of current trunk tag"
  local trunk_revision_2="$(cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep '^trunk ' | awk '{print $4}')"

  echo "*** {18} check trunk revision progress"
  [ $(( $trunk_revision_1 + 5 )) -eq $trunk_revision_2 ] || return 56

  # ============================================================================

  echo "*** {19} check if we have undo tags"
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$trunk_tag"      || return 57
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag" || return 58

  echo "*** {19} try to delete undo tags (should fail)"
  cvmfs_server tag -r $trunk_tag -f                    $CVMFS_TEST_REPO && return 59
  cvmfs_server tag -f -r $prev_trunk_tag               $CVMFS_TEST_REPO && return 60
  cvmfs_server tag -r $trunk_tag -r $prev_trunk_tag -f $CVMFS_TEST_REPO && return 61

  echo "*** {19} check that we still have undo tags"
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$trunk_tag"      || return 62
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag" || return 63

  # ============================================================================

  echo "*** {20} perform an undo-rollback to get rid of $prev_trunk_tag"
  cvmfs_server rollback -f $CVMFS_TEST_REPO || return 64

  echo "*** {20} check if $prev_trunk_tag is gone"
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag" && return 64

  echo "*** {20} try to recreate $prev_trunk_tag (should fail)"
  cvmfs_server tag -a $prev_trunk_tag $CVMFS_TEST_REPO && return 65

  echo "*** {20} check if $prev_trunk_tag is still not there"
  cvmfs_server tag -l -x $CVMFS_TEST_REPO | grep -q "$prev_trunk_tag" && return 66

  return 0
}

