#!/bin/bash
# shellcheck shell=sh
# shellcheck disable=SC2034 
# shellcheck disable=SC2059
# shellcheck disable=SC1091
# shellcheck disable=SC1090

set -e
#set -x

if [ "$(id -u)" -ne 0 ]; then
	echo "$0 needs root: please use sudo."
	exit 1
fi

# Source Auxilium (args parser)
. /usr/share/auxilium/auxilium.sh

auxilium_init "$(basename "$0")" -m 'Reconfigure an HDD after replacing it'

auxilium_add fo_name -t positional -m 'Resolve by FO name (sdX or Box0Disk0)'

if [ -f "/usr/share/ferreus-orbit/common.sh" ]; then
	. "/usr/share/ferreus-orbit/common.sh"
elif [ -f "share/common.sh" ] ; then
	. "share/common.sh"
elif [ -e "../share/common.sh" ] ; then
	. "../share/common.sh"
else
	echo "Cannot load common.sh: exiting."
	exit 1
fi

auxilium_parse "$@"

fo_lock

if [ -z "$AUXILIUM_ARG_sh_completion" ]; then
	fo_init
fi

if [ "$FO_DEFAULT_RAID0" -eq 1 ]; then
  fo-configure-raid0
fi

get_maj_min(){
  majmin=$(grep ",${1}" "${VAR_PATH}/maj_min_map"| cut -d',' -f1)
  if [ -z "$majmin" ]; then
 		for realname in /dev/sd[a-z]; do
			if ! mount | grep -q "${realname}"; then
		    eval "$(udevadm info -q property --export "${realname}")"
        if [ "$(fo_get_sorted_name)" = "$1" ]; then
          # shellcheck disable=SC2046
          # shellcheck disable=SC2183
          majmin=$(printf "%d:%d" $(stat -c "0x%t 0x%T" "${realname}"))
          break
        fi
      fi
    done
  fi
  if [ -z "$majmin" ]; then
  		for realname in /dev/sd[a-z]; do
			if ! mount | grep -q "${realname}"; then
        echo "I found the disk ${realname} unmounted, do you want use it ? (y|n)" >&2
        read -r response
        if [ "$response" = "y" ]; then
          # shellcheck disable=SC2183 # Stat return 2 args
          # shellcheck disable=SC2046 # For preserve 2 args
          majmin=$(printf "%d:%d" $(stat -c "0x%t 0x%T" "${realname}"))
          break
        fi
      fi
    done
  fi
  echo "$majmin"
}

get_real_disk(){
  if [ -L "${SORTED_PATH}/$1" ];then
    _kname=$(realpath "${SORTED_PATH}/$1")
    if ! mount | grep -q "${_kname}"; then
      echo "This device (${_kname}) seems to be already mounted !"
  		for realname in /dev/sd[a-z]; do
        if ! mountpoint -q "${realname}"; then
          echo "I found the disk ${realname} unmounted, do you want use it ? (y|n)" >&2
          read -r response
          if [ "$response" = "y" ]; then
            realdisk=$(basename "$realname")
            break
          fi
        fi
      done
    else
      realdisk=$(basename "$_kname")
    fi
  else
    maj_min=$(get_maj_min "$1")
    realdisk="$(ls "/sys/dev/block/${maj_min}/device/block")"
  fi
  echo "$realdisk"
}

fo_wait_until_mounted () {
	_fo_wait_MOUNT_POINT=${1}

	_fo_wait_TIMESTAMP_TIMEOUT=$(date -d "now + 30 sec" +%s)
	while ! mountpoint -q "${_fo_wait_MOUNT_POINT}"  && [ "$(date +%s)" -lt "${_fo_wait_TIMESTAMP_TIMEOUT}" ] ; do
		sleep 1
	done
	if ! mountpoint -q "${_fo_wait_MOUNT_POINT}" ; then
		echo "Device not mounted after the mount command and 30 seconds timeout: exiting."
		exit 1
	fi
}

# shellcheck disable=SC2154
readonly OLD_DISK="$AUXILIUM_ARG_fo_name"

REALDISK=$(get_real_disk "$OLD_DISK")
readonly REALDISK
OLD_UUID=$(grep -m1 "/srv/node/${OLD_DISK}" /etc/fstab| awk '{print $1}' | sed -e 's/[#]*UUID=//')
readonly OLD_UUID

echo "===> udevadm trigger new devices"
udevadm trigger -t devices

eval "$(udevadm info -q property --export "/dev/${REALDISK}" 2>/dev/null)"

echo "===> Updater firmware of /dev/${REALDISK}"
fo-fw-updater "/dev/$REALDISK"

echo "===> Formating /dev/${REALDISK} (for /srv/node/${OLD_DISK})"
mkfs.xfs -f "/dev/${REALDISK}" || exit 1
echo "===> Get new UUID"
NEW_UUID=$(blkid -o value -s UUID "/dev/${REALDISK}")
readonly NEW_UUID
echo "===> Uncommenting from fstab, ${OLD_UUID} to ${NEW_UUID}"
sed -i "s/[#]*UUID=${OLD_UUID}/UUID=${NEW_UUID}/" /etc/fstab
echo "===> Reloading systemd after fstab edit"
systemctl daemon-reload
sleep 1
echo "===> Mounting /srv/node/${OLD_DISK}"
mount "/srv/node/${OLD_DISK}" || exit 1

fo_wait_until_mounted "/srv/node/${OLD_DISK}"

echo "===> Changing disk's owner"
chown swift:swift "/srv/node/${OLD_DISK}"
echo "===> Truncating /var/log/kern-legacy.log"
if [ -e /var/log/kern-legacy.log ] ; then
  printf "" >/var/log/kern-legacy.log
fi

echo "Cleaning cache"
rm -f "${VAR_PATH}/fo-*"

echo
echo "Device /srv/node/${OLD_DISK} correctly replace"

