#!/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>] --type docker/k8s <k8s_namespace>"
  echo "  --max-delay : optional max delay in seconds"
  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)"
}

# Max delay
MAX_DELAY=120

if [[ "$1" == "--max-delay" ]]; then
  MAX_DELAY=$2
  shift # past argument
  shift # past value
fi

# Set up global variables
IS_DOCKER=false
K8S_NAMESPACE=""

if [[ $# -lt 2 ]]; then
  echo "error: invalid number of arguments"
  usage
  exit 1
fi

if [[ "$1" != "--type" ]]; then
  echo "error: unknown argument \"$1\""
  usage
  exit 1
fi

if [[ "$2" == "docker" ]]; then
  IS_DOCKER=true
elif [[ "$2" == "k8s" ]]; then
  IS_DOCKER=false
else
  echo "error: unknown type of executor \"$2\""
  usage
  exit 1
fi

if [[ "${IS_DOCKER}" == false ]]; then
  # 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"
fi

EOS_ROOT=/eos/dockertest/
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
   }' | 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
   }' | 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
