#!/bin/bash
cvmfs_test_name="Omit bulk chunks"
cvmfs_test_autofs_on_startup=false

CVMFS_TEST_644_REPLICA_NAME=
CVMFS_TEST_644_MOUNTPOINT=
cleanup() {
  [ -z $CVMFS_TEST_644_MOUNTPOINT ] || sudo umount $CVMFS_TEST_644_MOUNTPOINT > /dev/null 2>&1
  [ -z $CVMFS_TEST_644_REPLICA_NAME ] || sudo cvmfs_server rmfs -f $CVMFS_TEST_644_REPLICA_NAME
}

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

  echo "*** create a gc-eneabled repository named $CVMFS_TEST_REPO with user $CVMFS_TEST_USER"
  create_empty_repo $CVMFS_TEST_REPO $CVMFS_TEST_USER "NO" -z -g || return $?
  disable_auto_garbage_collection $CVMFS_TEST_REPO || return $?
  echo "*** enable legacy bulk chunks"
  echo "CVMFS_GENERATE_LEGACY_BULK_CHUNKS=true" | \
    sudo tee -a /etc/cvmfs/repositories.d/$CVMFS_TEST_REPO/server.conf

  echo "*** create a chunked file"
  start_transaction $CVMFS_TEST_REPO || return $?
  touch /cvmfs/$CVMFS_TEST_REPO/empty
  dd if=/dev/urandom of=/cvmfs/$CVMFS_TEST_REPO/32mb bs=$((1024*1024)) count=32
  local md5_32mb=$(md5sum /cvmfs/$CVMFS_TEST_REPO/32mb | awk '{print $1}')
  echo "*** md5sum of file: $md5_32mb"
  publish_repo $CVMFS_TEST_REPO || return $?

  local chunks=$(get_xattr chunks /var/spool/cvmfs/$CVMFS_TEST_REPO/rdonly/32mb)
  echo "*** number of chunks is $chunks"
  [ $chunks -gt 1 ] || return 10
  local bulk_hash=$(get_xattr hash /var/spool/cvmfs/$CVMFS_TEST_REPO/rdonly/32mb)
  echo "*** empty bulk hash is $bulk_hash"
  [ "x$bulk_hash" != "x" ] || return 12
  [ "x$bulk_hash" != "0000000000000000000000000000000000000000" ] || return 13
  check_repository $CVMFS_TEST_REPO -i || return 14

  echo "*** turn off legacy bulk chunks, republish big file"
  echo "CVMFS_GENERATE_LEGACY_BULK_CHUNKS=false" | \
    sudo tee -a /etc/cvmfs/repositories.d/$CVMFS_TEST_REPO/server.conf
  start_transaction $CVMFS_TEST_REPO || return $?
  touch /cvmfs/$CVMFS_TEST_REPO/32mb
  publish_repo $CVMFS_TEST_REPO || return $?

  get_xattr hash /var/spool/cvmfs/$CVMFS_TEST_REPO/rdonly/32mb && return 20
  check_repository $CVMFS_TEST_REPO -i || return 21

  md5_32mb_chunked=$(md5sum /cvmfs/$CVMFS_TEST_REPO/32mb | awk '{print $1}')
  echo "*** md5sum of file read in chunks: $md5_32mb_chunked"
  [ "x$md5_32mb" = "x$md5_32mb_chunked" ] || return 22

  echo "*** hardlinked, chunked files"
  start_transaction $CVMFS_TEST_REPO || return $?
  dd if=/dev/urandom of=/cvmfs/$CVMFS_TEST_REPO/hl1 bs=$((1024*1024)) count=32
  ln /cvmfs/$CVMFS_TEST_REPO/hl1 /cvmfs/$CVMFS_TEST_REPO/hl2
  local md5_ln=$(md5sum /cvmfs/$CVMFS_TEST_REPO/hl1 | awk '{print $1}')
  echo "*** md5sum of hard link: $md5_ln"
  publish_repo $CVMFS_TEST_REPO || return $?

  chunks=$(get_xattr chunks /var/spool/cvmfs/$CVMFS_TEST_REPO/rdonly/hl1)
  echo "*** number of chunks is $chunks"
  [ $chunks -gt 1 ] || return 30
  get_xattr hash /var/spool/cvmfs/$CVMFS_TEST_REPO/rdonly/ln && return 31
  local md5_ln_chunked=$(md5sum /cvmfs/$CVMFS_TEST_REPO/hl1 | awk '{print $1}')
  echo "*** md5sum of hard link read in chunks: $md5_ln_chunked"
  [ "x$md5_ln" = "x$md5_ln_chunked" ] || return 32
  md5_ln_chunked=$(md5sum /cvmfs/$CVMFS_TEST_REPO/hl2 | awk '{print $1}')
  echo "*** md5sum of other hard link read in chunks: $md5_ln_chunked"
  [ "x$md5_ln" = "x$md5_ln_chunked" ] || return 33

  start_transaction $CVMFS_TEST_REPO || return $?
  ln /cvmfs/$CVMFS_TEST_REPO/hl1 /cvmfs/$CVMFS_TEST_REPO/hl3
  publish_repo $CVMFS_TEST_REPO || return $?
  md5_ln_chunked=$(md5sum /cvmfs/$CVMFS_TEST_REPO/hl3 | awk '{print $1}')
  echo "*** md5sum of new hard link read in chunks: $md5_ln_chunked"
  [ "x$md5_ln" = "x$md5_ln_chunked" ] || return 34


  echo "*** change hash algorithm"
  echo "CVMFS_HASH_ALGORITHM=shake128" | \
    sudo tee -a /etc/cvmfs/repositories.d/$CVMFS_TEST_REPO/server.conf
  start_transaction $CVMFS_TEST_REPO || return $?
  touch /cvmfs/$CVMFS_TEST_REPO/32mb
  publish_repo $CVMFS_TEST_REPO || return $?
  md5_32mb_chunked=$(md5sum /cvmfs/$CVMFS_TEST_REPO/32mb | awk '{print $1}')
  echo "*** md5sum of file read in chunks: $md5_32mb_chunked"
  [ "x$md5_32mb" = "x$md5_32mb_chunked" ] || return 35
  chunks=$(get_xattr chunks /var/spool/cvmfs/$CVMFS_TEST_REPO/rdonly/32mb)
  echo "*** number of chunks is $chunks"
  [ $chunks -gt 1 ] || return 36


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


  echo "*** testing gc with omitted bulk hashes"
  start_transaction $CVMFS_TEST_REPO || return $?
  rm -f /cvmfs/$CVMFS_TEST_REPO/hl*
  publish_repo $CVMFS_TEST_REPO || return $?
  echo "*** empty publish to remove objects from trunk-previous tag"
  start_transaction $CVMFS_TEST_REPO || return $?
  publish_repo $CVMFS_TEST_REPO || return $?
  cvmfs_server gc -r0 -lf $CVMFS_TEST_REPO || return 40
  check_repository $CVMFS_TEST_REPO -i || return 41


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


  echo "*** testing replication with omitted bulk hashes"
  echo "*** install a cleanup function"
  trap cleanup EXIT HUP INT TERM

  load_repo_config $CVMFS_TEST_REPO
  local replica_name="$(get_stratum1_name $CVMFS_TEST_REPO)"
  CVMFS_TEST_644_REPLICA_NAME=$replica_name
  create_stratum1 $replica_name                          \
                  $CVMFS_TEST_USER                       \
                  $CVMFS_STRATUM0                        \
                  /etc/cvmfs/keys/${CVMFS_TEST_REPO}.pub || return 50
  sudo cvmfs_server snapshot $replica_name || return 51
  check_repository $replica_name -i || return 52

  echo "*** mount the Stratum1 repository on a local mountpoint"
  CVMFS_TEST_644_MOUNTPOINT="$(pwd)/mountpoint"
  do_local_mount $CVMFS_TEST_644_MOUNTPOINT $CVMFS_TEST_REPO $(get_repo_url $replica_name) \
   || return 53

  local md5_32mb_s1=$(md5sum $CVMFS_TEST_644_MOUNTPOINT/32mb | awk '{print $1}')
  echo "*** md5sum of file from stratum 1: $md5_32mb_s1"
  [ "x$md5_32mb" = "x$md5_32mb_s1" ] || return 54


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


  echo "*** Test grafting chunked files"
  start_transaction $CVMFS_TEST_REPO || return $?
  dd if=/dev/urandom bs=$((1024*1024)) count=20 2>/dev/null | \
    cvmfs_swissknife graft -i - -c 8 -o /cvmfs/$CVMFS_TEST_REPO/graft20m
  dd if=/dev/urandom bs=$((1024*1024)) count=5 2>/dev/null | \
    cvmfs_swissknife graft -i - -c 8 -o /cvmfs/$CVMFS_TEST_REPO/graft5m
  dd if=/dev/urandom bs=$((1024*1024)) count=32 2>/dev/null | \
    cvmfs_swissknife graft -i - -c 8 -b -o /cvmfs/$CVMFS_TEST_REPO/graftbulk
  ls -lah /cvmfs/$CVMFS_TEST_REPO
  publish_repo $CVMFS_TEST_REPO || return $?
  ls -lah /cvmfs/$CVMFS_TEST_REPO
  chunks=$(get_xattr chunks /var/spool/cvmfs/$CVMFS_TEST_REPO/rdonly/graft20m)
  echo "*** number of chunks is $chunks"
  [ $chunks -gt 1 ] || return 60
  get_xattr hash /var/spool/cvmfs/$CVMFS_TEST_REPO/rdonly/graft20m && return 62
  bulk_hash=$(get_xattr hash /var/spool/cvmfs/$CVMFS_TEST_REPO/rdonly/graftbulk)
  echo "*** bulk hash of grafted file is $bulk_hash"
  [ "x$bulk_hash" != "x" ] || return 63
  [ "x$bulk_hash" != "0000000000000000000000000000000000000000" ] || return 64
  [ "x$bulk_hash" != "0000000000000000000000000000000000000000-shake128" ] || return 64
  check_repository $CVMFS_TEST_REPO -c || return 65

  return 0
}
