#!/bin/bash

cvmfs_test_name="Ingest tarball to various subdirectories in the repository"
cvmfs_test_autofs_on_startup=false
cvmfs_test_suites="quick"

produce_tarball() {
  local tarball_name=$1
  local script_location=$2

  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"
  # the -P option create a tarball with a leading slash
  # the -H posix option creates nanosecond precision timestamps
  tar -H posix -Pcvf $tarball_name $(pwd)/tarball_foo

  rm -rf tarball_foo
}

cvmfs_run_test() {
  logfile=$1
  local scratch_dir=$(pwd)
  local tarfile=$scratch_dir/tarball.tar
  local dir=tar_dir
  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 "CVMFS_ENABLE_MTIME_NS=true" | sudo tee -a /etc/cvmfs/repositories.d/${CVMFS_TEST_REPO}/server.conf

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

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

  echo "*** ingesting the tarball in the directory $dir"
  cat $tarfile | cvmfs_server ingest --base_dir $dir --tar_file - $CVMFS_TEST_REPO || return $?
  local created_path=$repo_dir/$dir$(pwd)

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

  if [ ! -d $repo_dir/$dir/$(pwd)/tarball_foo ]; then
    return 1
  fi

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

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

    fi
  done

  file=$created_path/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 1
  else
    echo "*** Ingested file of size $file_size bytes: $file"
  fi

  if [ $file_size -eq 5120 ]; then
    echo "*** It compare well"
  fi

  ### We ingest the file into a subdir which contains leading and trailing slashes
  ### which should be removed by the sanitizer
  dir="to_be_sanitized"

  echo "*** ingesting the tarball in the directory $dir"
  cat $tarfile | cvmfs_server ingest --base_dir "///$dir///" --tar_file - $CVMFS_TEST_REPO || return $?
  local created_path=$repo_dir/$dir$(pwd)

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

  if [ ! -d $repo_dir/$dir/$(pwd)/tarball_foo ]; then
    return 1
  fi

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

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

    fi
  done

  file=$created_path/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 1
  else
    echo "*** Ingested file of size $file_size bytes: $file"
  fi

  if [ $file_size -eq 5120 ]; then
    echo "*** It compare well"
  fi

  ### Below we ingest the file with the --catalog option

  echo "*** ingesting tarball when generating a catalog"
  dir=tar_dir_with_catalog
  created_path=$repo_dir/$dir$(pwd)

  cat $tarfile | cvmfs_server ingest --catalog --base_dir $dir --tar_file - $CVMFS_TEST_REPO || return $?

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

  echo "check that the catalog was created and that can be accessed"
  cat $repo_dir/$dir/.cvmfscatalog > /dev/null || return 105

  if [ ! -d $created_path/tarball_foo ]; then
    return 1
  fi

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

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

    fi
  done

  file=$created_path/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 1
  else
    echo "*** Ingested file of size $file_size bytes: $file"
  fi

  if [ $file_size -eq 5120 ]; then
    echo "*** It compare well"
  fi

  echo "*** ingesting the tarball in the root of the repository"
  cat $tarfile | cvmfs_server ingest --base_dir / --tar_file - $CVMFS_TEST_REPO || return $?
  created_path=$repo_dir$(pwd)

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

  if [ ! -d $created_path/tarball_foo ]; then
    return 1
  fi

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

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

    fi
  done

  file=$created_path/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 1
  else
    echo "*** Ingested file of size $file_size bytes: $file"
  fi

  if [ $file_size -eq 5120 ]; then
    echo "*** It compare well"
  fi

  echo "checking nanosecond timestamps"
  echo "entry information of $file:"
  stat $file || return 50
  local mtime_ns=$(stat -c%y $file | cut -d. -f2 | awk '{print $1}')
  [ $mtime_ns -ne 0 ] || return 51

  echo "*** ingesting empty tarball with nested catalog"
  cat $script_location/layer.tar | cvmfs_server ingest --base_dir layer -c --tar_file - $CVMFS_TEST_REPO || return 42
  ls /cvmfs/$CVMFS_TEST_REPO/layer/.cvmfscatalog || return 42

  echo "*** ingesting absolute paths"

  cvmfs_server ingest --base_dir /cvmfs/$CVMFS_TEST_REPO/absolute_path1  --tar_file $tarfile || return 43
  ls /cvmfs/$CVMFS_TEST_REPO/absolute_path1/$(pwd)/tarball_foo || return 44

  echo "*** delete with absolute paths"
  cvmfs_server ingest -d /cvmfs/$CVMFS_TEST_REPO/absolute_path1/tarball_foo/a/1.txt || return 45
  echo "*** delete with multiple absolute paths"
  cvmfs_server ingest -d /cvmfs/$CVMFS_TEST_REPO/absolute_path1/tarball_foo/a/2.txt -d /cvmfs/$CVMFS_TEST_REPO/absolute_path1/tarball_foo/a/3.txt || return 46

  echo "** check mismatches in repository name"
  cvmfs_server ingest --base_dir /cvmfs/$CVMFS_TEST_REPO/absolute_path2  --tar_file $tarfile no.such.repository && return 47
  cvmfs_server ingest --base_dir /cvmfs/no.such.repository/absolute_path2  --tar_file $tarfile  && return 48
  cvmfs_server ingest -d /cvmfs/$CVMFS_TEST_REPO/absolute_path1/tarball_foo/a/b/2.txt -d /cvmfs/no.such.directory/absolute_path1/tarball_foo/a/b/3.txt && return 49


  echo "** check deletion of files with : in filename"
  cvmfs_server transaction $CVMFS_TEST_REPO || return 50
  echo "testwith:" > /cvmfs/$CVMFS_TEST_REPO/unlucky:filename || return 51
  cvmfs_server publish $CVMFS_TEST_REPO || return 52
  cvmfs_server ingest -d /cvmfs/$CVMFS_TEST_REPO/unlucky:filename || return 53

  return 0
}

