#!/bin/bash -e

# ******************************************************************************
# EOS - the CERN Disk Storage System
# Copyright (C) 2020 CERN/Switzerland
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ******************************************************************************

SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
source ${SCRIPTPATH}/eos-test-utils

function usage() {
  echo "usage: $(basename $0) [--max-delay <sec_delay>] [--root-dir <path>] --type docker/k8s <k8s_namespace>"
  echo "  --max-delay : optional max delay in seconds"
  echo "  --root-dir  : eos root test directory "
  echo "       docker : script runs in a Docker based setup"
  echo "       k8s    : script runs in a Kubernetes setup and requires a namespace argument"
}

function cleanup() {
  rm -rf /tmp/conv_test_file.dat
  exec_cmd eos-cli1 "eos rm -rF $EOS_CONVERTER_DIR"
  exec_cmd eos-cli1 "eos rmdir $(dirname $EOS_CONVERTER_DIR)"
}

# Set up global variables
IS_DOCKER=false
IS_KUBERNETES=false
IS_LOCAL=true
K8S_NAMESPACE=""
MAX_DELAY=120
EOS_ROOT=/eos/dockertest/

while [[ $# -gt 1 ]]; do
  if [[ "$1" == "--help" || "$1" == "-h" ]]; then
    usage
    exit 0
  elif [[ "$1" == "--max-delay" ]]; then
    MAX_DELAY=$2
    shift # past argument
    shift # past value
  elif [[ "$1" == "--root-dir" ]]; then
    EOS_ROOT=$2
    shift
    shift
  elif [[ "$1" == "--type" ]]; then
    if [[ "$2" == "docker" ]]; then
      IS_DOCKER=true
      IS_LOCAL=false
      shift
    elif [[ "$2" == "k8s" ]]; then
      IS_KUBERNETES=true
      IS_LOCAL=false
      # For the Kubernetes setup we also need a namespace argument
      if [[ $# -lt 3 ]]; then
        echo "error: missing Kubernetes namespace argument"
        usage
        exit 1
      fi

      K8S_NAMESPACE="$3"
      shift
      shift
    fi
  else
    echo "error: unknown argument \"$1\""
    usage
    exit 1
  fi
done

EOS_CONVERTER_DIR=${EOS_ROOT}/converter_dir/test_dir/
exec_cmd eos-cli1 "dd if=/dev/urandom of=/tmp/conv_test_file.dat bs=1M count=30 &&
                   eos -r 0 0 space config default space.converter=on
                   eos -r 0 0 mkdir -p ${EOS_CONVERTER_DIR} &&
                   eos -r 0 0 attr set default=replica ${EOS_CONVERTER_DIR} &&
                   eos cp /tmp/conv_test_file.dat ${EOS_CONVERTER_DIR}/test_replica.dat &&
                   eos cp /tmp/conv_test_file.dat ${EOS_CONVERTER_DIR}/test_raiddp.dat"
# Wait for the conversion to be done
START_TIME=$(date +%s)

for TEST_FILE in ${EOS_CONVERTER_DIR}/test_replica.dat ${EOS_CONVERTER_DIR}/test_raiddp.dat; do
  # Note we use xargs to trim the output
  ORIG_FINFO=$(exec_cmd eos-cli1 "eos fileinfo ${TEST_FILE} -m | \
    sed -e '{
     s/fsid=[[:digit:]]//g;
     s/fsdel=[[:digit:]]//g;
     s/layout=[[:alnum:]]\+[[:space:]]//g;
     s/nstripes=[[:digit:]]\+[[:space:]]//g;
     s/lid=[[:digit:]]\+[[:space:]]//g;
     s/nrep=[[:digit:]]\+[[:space:]]//g;
     s/xattrn=sys.fs.tracking xattrv=[-/+[:digit:]]\+[[:space:]]//g
   }' | xargs")
  ORIG_LOCATIONS=$(exec_cmd eos-cli1 "eos -j fileinfo ${TEST_FILE} | jq -r .locations[].fsid | tr '\n' ' ' | xargs")

  if [[ "${TEST_FILE}" == *raiddp* ]]; then
    exec_cmd eos-cli1 "eos file convert ${TEST_FILE} raiddp:6"
  else
    exec_cmd eos-cli1 "eos file convert --rewrite ${TEST_FILE}"
  fi

  while
    CURRENT_TIME=$(date +%s)
    NEW_LOCATIONS=$(exec_cmd eos-cli1 "eos -j fileinfo ${TEST_FILE} | jq -r .locations[].fsid | tr '\n' ' ' | xargs")

    if [[ "${ORIG_LOCATIONS}" != "${NEW_LOCATIONS}" ]]; then
      echo "info: file successfully converted"
      break
    fi

    if (( $((${CURRENT_TIME} - ${START_TIME})) >= ${MAX_DELAY} )); then
      echo "error: conversion failed"
      cleanup
      exit 1
    else
      echo "info: sleep for 2 seconds waiting for conversion, `secs_to_human $((${CURRENT_TIME} - ${START_TIME}))` passed"
      sleep 2
    fi
  do
    :
  done

  NEW_FINFO=$(exec_cmd eos-cli1 "eos fileinfo ${TEST_FILE} -m | \
    sed -e '{
     s/fsid=[[:digit:]]//g;
     s/fsdel=[[:digit:]]//g;
     s/layout=[[:alnum:]]\+[[:space:]]//g;
     s/nstripes=[[:digit:]]\+[[:space:]]//g;
     s/lid=[[:digit:]]\+[[:space:]]//g;
     s/nrep=[[:digit:]]\+[[:space:]]//g;
     s/xattrn=sys.fs.tracking xattrv=[-/+[:digit:]]\+[[:space:]]//g
   }' | xargs")

  if [[ "${ORIG_FINFO}" != "${NEW_FINFO}" ]]; then
    echo "error: converted file metadata does not match the original one"
    echo "original finfo: \"${ORIG_FINFO}\""
    echo "new  finfo    : \"${NEW_FINFO}\""
    cleanup
    exit 1
  fi
done

cleanup
exit 0
