#!/bin/bash

cvmfs_test_name="Ingest tarball in a repo and while removing base-dir's"
cvmfs_test_autofs_on_startup=false

produce_tarball() {
  local tarball_name=$1

  mkdir tarball_foo
  mkdir -p tarball_foo/a/b/c
  mkdir -p tarball_foo/d/e/f

  dd bs=1024 count=2 2>/dev/null </dev/urandom >tarball_foo/a/1.txt
  dd bs=1024 count=2 2>/dev/null </dev/urandom >tarball_foo/a/2.txt
  dd bs=1024 count=2 2>/dev/null </dev/urandom >tarball_foo/a/3.txt
  dd bs=1024 count=2 2>/dev/null </dev/urandom >tarball_foo/a/b/1.txt
  dd bs=1024 count=2 2>/dev/null </dev/urandom >tarball_foo/a/b/2.txt
  dd bs=1024 count=2 2>/dev/null </dev/urandom >tarball_foo/a/b/3.txt
  dd bs=1024 count=2 2>/dev/null </dev/urandom >tarball_foo/a/b/c/1.txt
  dd bs=1024 count=2 2>/dev/null </dev/urandom >tarball_foo/a/b/c/2.txt
  dd bs=1024 count=2 2>/dev/null </dev/urandom >tarball_foo/a/b/c/3.txt

  dd bs=1024 count=5 2>/dev/null  </dev/urandom >tarball_foo/d/e/f/foo.txt

  echo "*** Generating a tarball in $tarball_name"
  tar -cvf $tarball_name tarball_foo/

  rm -rf tarball_foo
}

cvmfs_run_test() {
  logfile=$1
  local scratch_dir=$(pwd)
  local tarfile=$scratch_dir/tarball.tar
  local to_remove_dir=tar_dir_remove
  local to_keep_dir=tar_dir_keep
  local repo_dir=/cvmfs/$CVMFS_TEST_REPO

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

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

  echo "*** generating a tarball $tarfile"
  produce_tarball $tarfile

  echo "*** ingesting the tarball in the directory $to_remove_dir"
  cvmfs_server ingest --base_dir $to_remove_dir --tar_file $tarfile $CVMFS_TEST_REPO || return $?

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

  echo "*** check that we actually put the files in $to_remove_dir"
  if [ ! -d $repo_dir/$to_remove_dir/tarball_foo ]; then
    return 1
  fi

  for d in a a/b a/b/c; do
    if [ ! -d $repo_dir/$to_remove_dir/tarball_foo/$d ]; then
      echo "*** Error not found directory: $repo_dir/$to_remove_dir/tarball_foo/$d"
      return 2
    else
      echo "*** Ingested directory: $repo_dir/$to_remove_dir/tarball_foo/$d"

      for f in 1 2 3; do
        file=$repo_dir/$to_remove_dir/tarball_foo/$d/$f.txt
        if [ ! -f $file ] || [ $(wc -c <$file) -ne 2048 ]; then
          echo "*** Error not found file: $file"
          return 3
        else
          echo "*** Ingested file of size 2048 bytes: $file"
        fi
      done

    fi
  done

  file=$repo_dir/$to_remove_dir/tarball_foo/d/e/f/foo.txt
  file_size=$(wc -c <$file)
  if [ ! -f $file ] || [ $file_size -ne 5120 ]; then
    echo "*** Error not found file of size 5120: $file"
    return 4
  else
    echo "*** Ingested file of size $file_size bytes: $file"
  fi

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

  echo "*** the files to remove are actually in $to_remove_dir"
  echo "*** ingest another tarball in $to_keep_dir while removing everything in $to_remove_dir"

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

  echo "*** ingesting the tarball in the directory $to_keep_dir"
  cvmfs_server ingest --base_dir $to_keep_dir --tar_file $tarfile -d $to_remove_dir $CVMFS_TEST_REPO || return $?

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

  echo "*** check that we actually put the files in $to_keep_dir"
  if [ ! -d $repo_dir/$to_keep_dir/tarball_foo ]; then
    return 5
  fi

  for d in a a/b a/b/c; do
    if [ ! -d $repo_dir/$to_keep_dir/tarball_foo/$d ]; then
      echo "*** Error not found directory: $repo_dir/$to_keep_dir/tarball_foo/$d"
      return 6
    else
      echo "*** Ingested directory: $repo_dir/$to_keep_dir/tarball_foo/$d"

      for f in 1 2 3; do
        file=$repo_dir/$to_keep_dir/tarball_foo/$d/$f.txt
        if [ ! -f $file ] || [ $(wc -c <$file) -ne 2048 ]; then
          echo "*** Error not found file: $file"
          return 7
        else
          echo "*** Ingested file of size 2048 bytes: $file"
        fi
      done

    fi
  done

  file=$repo_dir/$to_keep_dir/tarball_foo/d/e/f/foo.txt
  file_size=$(wc -c <$file)
  if [ ! -f $file ] || [ $file_size -ne 5120 ]; then
    echo "*** Error not found file of size 5120: $file"
    return 8
  else
    echo "*** Ingested file of size $file_size bytes: $file"
  fi

  echo "*** checking that we have actually removed the $to_remove_dir directory"
  if [ -d $repo_dir/$to_remove_dir ]; then
    echo "*** Error directory not removed $repo_dir/$to_remove_dir"
    return 9
  else
    echo "*** Directory actually removed $repo_dir/$to_remove_dir"
  fi

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

  echo "*** we removed the base directory while ingesting another tar"
  echo "*** trying to remove files and directory without ingesting anything"

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

  echo "*** trying to remove a non existing file"
  cvmfs_server ingest -d $to_keep_dir/non_existing_file.tar $CVMFS_TEST_REPO || return $?

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


  echo "*** trying to remove a single file"
  file=$to_keep_dir/tarball_foo/a/b/c/3.txt
  cvmfs_server ingest -d $file $CVMFS_TEST_REPO || return $?

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

  if [ -f $file ]; then
    echo "*** Error found file $file"
    return 10
  else
    echo "*** Removed file: $file"
  fi

  echo "*** trying to remove multiple file"
  file1=$to_keep_dir/tarball_foo/a/b/c/1.txt
  file2=$to_keep_dir/tarball_foo/a/b/c/2.txt
  cvmfs_server ingest -d $file1 -d $file2 $CVMFS_TEST_REPO || return $?

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

  if [ -f $file1 ] || [ -f $file2 ]; then
    echo "*** Error found file $file1 or $file2"
    return 11
  else
    echo "*** Removed files: $file1 and $file2"
  fi

  return 0
}

