#!/bin/bash
cvmfs_test_name="Create Stratum1 Snapshot In Symlinked Backend"
cvmfs_test_autofs_on_startup=false

produce_files_in() {
  local working_dir=$1

  pushdir $working_dir

  cp_bin $working_dir

  popdir
}

CVMFS_TEST_538_SELINUX_DISABLED=0
CVMFS_TEST_538_S1_NAME=
CVMFS_TEST_538_MOUNTPOINT=
CVMFS_TEST_538_ALT_BACKEND=
cleanup() {
  echo "running cleanup..."
  [ $CVMFS_TEST_538_SELINUX_DISABLED -eq 0 ] || sudo setenforce 1
  [ -z $CVMFS_TEST_538_S1_NAME ]             || sudo cvmfs_server rmfs -f $CVMFS_TEST_538_S1_NAME
  [ -z $CVMFS_TEST_538_MOUNTPOINT ]          || sudo umount $CVMFS_TEST_538_MOUNTPOINT
  [ -z $CVMFS_TEST_538_ALT_BACKEND         ] || sudo rm -fR $CVMFS_TEST_538_ALT_BACKEND
}

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

  local scratch_dir=$(pwd)
  mkdir reference_dir
  local reference_dir=$scratch_dir/reference_dir

  local mnt_point="$(pwd)/mountpount"
  local replica_name="$(get_stratum1_name $CVMFS_TEST_REPO)"

  local backend_dir="/srv/cvmfs/${replica_name}"
  local alternative_backend="/opt/cvmfs"
  local symlink_destination="${alternative_backend}/${replica_name}"

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

  echo "starting transaction to edit repository"
  start_transaction $CVMFS_TEST_REPO || return $?

  echo "putting some stuff in the new repository"
  produce_files_in $repo_dir || return 3

  echo "putting exactly the same stuff in the scratch space for comparison"
  produce_files_in $reference_dir || return 4

  local publish_log_1="publish_1.log"
  echo "creating CVMFS snapshot (logging to $publish_log_1)"
  publish_repo $CVMFS_TEST_REPO > $publish_log_1 2>&1 || return $?

  echo "compare the results of cvmfs to our reference copy"
  compare_directories $repo_dir $reference_dir || return $?

  echo "check catalog and data integrity"
  check_repository $CVMFS_TEST_REPO -i || return $?

  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

  echo "create symlinked backend for Stratum1"
  if [ -d $backend_dir ]; then
    echo -n "removing old backend directory... "
    sudo rm -fR $backend_dir || { echo "fail!"; return 5; }
    echo "done"
  fi
  CVMFS_TEST_538_ALT_BACKEND="$alternative_backend"
  sudo mkdir -p $symlink_destination || return 6
  sudo chown $CVMFS_TEST_USER:$CVMFS_TEST_USER $symlink_destination || return 6
  sudo ln --symbolic $symlink_destination $backend_dir || return 7

  echo "register cleanup trap"
  trap cleanup EXIT HUP INT TERM || return $?

  if has_selinux; then
    echo "make sure that SELinux does not interfere"
    CVMFS_TEST_538_SELINUX_DISABLED=1
    sudo setenforce 0 || return 16
  fi

  echo "create Stratum1 repository on the same machine"
  load_repo_config $CVMFS_TEST_REPO
  CVMFS_TEST_538_S1_NAME="$replica_name"
  create_stratum1 $replica_name                          \
                  $CVMFS_TEST_USER                       \
                  $CVMFS_STRATUM0                        \
                  /etc/cvmfs/keys/${CVMFS_TEST_REPO}.pub || return 8

  echo "create a Snapshot of the Stratum0 repository in the just created Stratum1 replica"
  cvmfs_server snapshot $replica_name || return 9

  echo "check if there is snapshot data in the symlink destination"
  [ -f ${symlink_destination}/.cvmfspublished ] || return 10
  [ -d ${symlink_destination}/data ]            || return 11

  echo "mount the Stratum1 repository on a local mountpoint"
  mkdir $mnt_point cache
  cat > private.conf << EOF
CVMFS_CACHE_BASE=$(pwd)/cache
CVMFS_RELOAD_SOCKETS=$(pwd)/cache
CVMFS_SERVER_URL=http://127.0.0.1/cvmfs/$replica_name
CVMFS_HTTP_PROXY=DIRECT
CVMFS_PUBLIC_KEY=/etc/cvmfs/keys/${CVMFS_TEST_REPO}.pub
EOF
  CVMFS_TEST_538_MOUNTPOINT="$mnt_point"
  cvmfs2 -d -o config=private.conf test.cern.ch $mnt_point >> cvmfs2_output.log 2>&1 || return 12

  echo "check the integrity of the stratum 1"
  check_repository $replica_name -i || return 13

  echo "check if the Stratum1 repository contains exactly the same as the reference copy"
  compare_directories $mnt_point $reference_dir || return 14

  return 0
}

