#!/bin/sh

echo "Staring NVIDIA Fabric Manager installation"

echo "Checking for running Fabric Manager service"

STATUS=`systemctl is-active nvidia-fabricmanager`
  if [ ${STATUS} = 'active' ] || [ ${STATUS} = 'activating' ]; then
    echo "Fabric Manager service is running, stopping the same....."
    systemctl stop nvidia-fabricmanager
  else 
    echo "Fabric Manager service is not running....."
  fi

echo "Checking for running Fabric Manager process"

# Check if nv-fabricmanager is still running, if so, send SIGTERM,
# and if FM doesn't exit after 90sec, send SIGKILL. This form of
# terminating is similar to systemctl stop.
fm_proc_name="nv-fabricmanager"
if pidof "$fm_proc_name" > /dev/null; then
  echo "Fabric Manager process is running, stopping the same....."

  timeout=90
  check_interval=5

  # Send SIGTERM
  killall -TERM "$fm_proc_name"

  start_time=$(date +%s)
  end_time=$((start_time + timeout))

  while [ $(date +%s) -le "$end_time" ]; do
    # Check if the process still exists
    if ! pidof "$fm_proc_name" > /dev/null; then
      echo "Fabric Manager process terminated gracefully."
      break
    fi

    sleep "$check_interval"
  done

  # If the process hasn't exited after the timeout, send SIGKILL
  if pidof "$fm_proc_name" > /dev/null; then 
    echo "Fabric Manager process is still running, killing the same....."
    killall -KILL "$fm_proc_name"
  fi
else
  echo "Fabric Manager process is not running....."
fi

# copy all the files
echo "Copying files to desired location"
# choose lib location based on system arch
ARCH_TYPE_CMD=`uname -m`
LIB_LOC="/usr/lib/x86_64-linux-gnu"
if [ ${ARCH_TYPE_CMD} = 'aarch64' ]; then
    echo "detected aarch64 and changing lib location to /usr/lib/aarch64-linux-gnu...."
    LIB_LOC="/usr/lib/aarch64-linux-gnu"
fi

cp ${PWD}/libnvfm.so.1 ${LIB_LOC}
cp -P ${PWD}/libnvfm.so   ${LIB_LOC}

cp ${PWD}/nv-fabricmanager  /usr/bin
cp ${PWD}/nvswitch-audit  /usr/bin
cp ${PWD}/nvidia-fabricmanager.service  /lib/systemd/system
cp ${PWD}/nvidia-fabricmanager-start.sh /usr/bin
chmod +x /usr/bin/nvidia-fabricmanager-start.sh

mkdir /usr/share/nvidia  > /dev/null 2>&1
mkdir /usr/share/nvidia/nvswitch/  > /dev/null 2>&1
cp ${PWD}/dgx2_hgx2_topology          /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxa100_hgxa100_topology    /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxh100_hgxh100_topology    /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxh800_hgxh800_topology    /usr/share/nvidia/nvswitch/
cp ${PWD}/mgxh20_nvl16_topology       /usr/share/nvidia/nvswitch/
cp ${PWD}/fabricmanager.cfg           /usr/share/nvidia/nvswitch/
cp ${PWD}/fabricmanager_multinode.cfg /usr/share/nvidia/nvswitch/
cp ${PWD}/nv_fm_agent.h               /usr/include
cp ${PWD}/nv_fm_types.h               /usr/include

# List of FM multi-node specific topology files
cp ${PWD}/dgxgh200_hgxgh200_8gpus_topology /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxgh200_hgxgh200_16gpus_topology /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxgh200_hgxgh200_16gpus_trunk_connections.csv /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxgh200_hgxgh200_16gpus_osfp_connections.csv /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxgh200_hgxgh200_16gpus_osfp_cable_connections.csv /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxgh200_hgxgh200_32gpus_topology /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxgh200_hgxgh200_32gpus_trunk_connections.csv /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxgh200_hgxgh200_32gpus_osfp_connections.csv /usr/share/nvidia/nvswitch/
cp ${PWD}/dgxgh200_hgxgh200_32gpus_osfp_cable_connections.csv /usr/share/nvidia/nvswitch/
cp ${PWD}/gh200_nvlink_32gpus_topology /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl36r1_c2g4_topology /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl36r1_c2g2_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl72r1_c2g4_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl72r2_c2g4_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl72r2_c2g2_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl576r4_c2g4_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl576r16_c2g4_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl8r1_c2g4_etf_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl8r1_c2g4_etf_nso_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb200_nvl4r1_c2g2_etf_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb300_nvl72r1_c2g4_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb300_nvl72r2_c2g4_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/gb300_nvl72r1_c2g4_kyber_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/vr_nvl72r1_c2g4_topology  /usr/share/nvidia/nvswitch/
cp ${PWD}/vr_nvl8r1_c2g4_rtf_topology  /usr/share/nvidia/nvswitch/

mkdir /usr/share/doc/nvidia-fabricmanager > /dev/null 2>&1
cp ${PWD}/LICENSE  /usr/share/doc/nvidia-fabricmanager
cp ${PWD}/third-party-notices.txt  /usr/share/doc/nvidia-fabricmanager

# enable Fabric Manager service
systemctl enable nvidia-fabricmanager

# let the user start FM service manually.
echo "Fabric Manager installation completed."
echo "Note: Fabric Manager service is not started. Start it using systemctl commands (like systemctl start nvidia-fabricmanager)"
