#!/bin/bash
source $HOME/.gamerc

SCRIPT_NAME=$(basename "$0")
LOCK_FILE="/tmp/${SCRIPT_NAME}.lock"

exec 200>"${LOCK_FILE}"
flock -n 200 || {
	echo "Another instance is running. Exiting."
	exit 1
}

if ! command -v taskset &> /dev/null; then
	# Check OS Debian to do do the security settings
	OS_DISTRO=$(cat /etc/os-release | grep ^ID= | sed 's/ID=//;s/"//g')
	if [ "${OS_DISTRO}" == "debian" -o "${OS_DISTRO}" == "ubuntu" ]; then
		sudo apt-get update
		sudo apt-get install -y util-linux
	elif [ "${OS_DISTRO}" == "centos" -o "${OS_DISTRO}" == "fedora" ]; then
		sudo yum -y install util-linux
	fi
fi

array_diff() {
  local -n a1=$1
  local -n a2=$2
  local result=()

  for val in "${a1[@]}"; do
    skip=false
    for compare in "${a2[@]}"; do
      if [[ "$val" == "$compare" ]]; then
        skip=true
        break
      fi
    done
    if ! $skip; then
      result+=("$val")
    fi
  done

  echo "${result[@]}"
}

FIX_SERVER_TOTAL_NUM=${#FIX_SERVER_LISTS[@]}
echo "FIX_SERVER_TOTAL_NUM => $FIX_SERVER_TOTAL_NUM"

if [ "${ENABLE_FIX_CPU_FOR_GAMESERVERS}" == "1" ]; then
	FIX_CPU_ID_STR=$(cat /proc/cmdline | tr ' ' '\n' | grep isolcpus | awk -F"=" '{print $2}')
	IFS="," read -ra FIX_CPU_ID_LISTS <<< "${FIX_CPU_ID_STR}"
	FIX_CPU_ID_TOTAL_NUM=${#FIX_CPU_ID_LISTS[@]}
	
	echo "FIX_CPU_ID_TOTAL_NUM => $FIX_CPU_ID_TOTAL_NUM"
	if [ "${FIX_CPU_ID_TOTAL_NUM}" -gt 0 ]; then
		STRING_CHECK=$($HOME/bin/get_all_server_cpu_affinity_into_arr)
		read -ra ARRAY_CHECK <<< "$STRING_CHECK"
		
		if [ ${#ARRAY_CHECK[@]} -eq 0 ]; then
			if [ "${FIX_CPU_ID_TOTAL_NUM}" -ge "${FIX_SERVER_TOTAL_NUM}" ]; then
				LOOP_FIX_SERVER_LISTS=("${FIX_SERVER_LISTS[@]:0:${FIX_SERVER_TOTAL_NUM}}")
			else
				LOOP_FIX_SERVER_LISTS=("${FIX_SERVER_LISTS[@]:0:${FIX_CPU_ID_TOTAL_NUM}}")
			fi

			for idx in ${!LOOP_FIX_SERVER_LISTS[@]}; do
				server=${LOOP_FIX_SERVER_LISTS[$idx]}
				while ! ps -ef | egrep -v 'grep|rsync' | grep "./${server}" | awk -F" " '{print $2}' > /dev/null; do
					sleep 1 # Check every second
				done

				PROCESS_ID=$(ps -ef | egrep -v 'grep|rsync' | grep "./${server}" | awk -F" " '{print $2}')

				echo "$server ( ${PROCESS_ID} ) => ${FIX_CPU_ID_LISTS[$idx]} ( $idx )"
				taskset -cp ${FIX_CPU_ID_LISTS[$idx]} ${PROCESS_ID}
				if [ "$HOST_NAME" == "TEST" -o "$HOST_NAME" == "SUB" -o "$HOST_NAME" == "SUBMIT" -o "$HOST_NAME" == "DATA" -o "$HOST_NAME" == "DLC" -o "$HOST_NAME" == "TIME1" -o "$HOST_NAME" == "MEDIA" ] ; then
					ENVIRONMENT="TEST"
				else
					ENVIRONMENT="LIVE"
				fi
				ssh CTRL "psql -U postgres WebTool -c \"INSERT INTO monitor_server_cpu_affinity (environment, host_name, process_name, process_id, cpu_id) VALUES ('$ENVIRONMENT', '$HOST_NAME', '$server', ${PROCESS_ID}, '${FIX_CPU_ID_LISTS[$idx]}');\""
			done
		else
			string_1=$(ps -eo pid,pcpu,comm --sort=-pcpu | grep -v SKServer | grep Server | awk '{print $3}' | head -n ${FIX_CPU_ID_TOTAL_NUM} | tr '\n' ' ')
			string_2=$($HOME/bin/get_all_server_cpu_affinity_into_arr)                                          
			read -ra array_1 <<< "$string_1"
			read -ra array_2 <<< "$string_2"                                                          
		
			diff_1=($(array_diff array_1 array_2))
			diff_2=($(array_diff array_2 array_1))
		
			if [ ${#array_2[@]} -eq 0 ]; then
				for idx in ${!array_1[@]}; do
					server_new=${array_1[$idx]}
					pid_new=$(ps -eo pid,pcpu,comm --sort=-pcpu | grep ${server_new} | awk '{print $1}')
		
					taskset -cp ${cpu_id} ${pid_new}
					if [ "$HOST_NAME" == "TEST" -o "$HOST_NAME" == "SUB" -o "$HOST_NAME" == "SUBMIT" -o "$HOST_NAME" == "DATA" -o "$HOST_NAME" == "DLC" -o "$HOST_NAME" == "TIME1" -o "$HOST_NAME" == "MEDIA" ] ; then
						ENVIRONMENT="TEST"
					else
						ENVIRONMENT="LIVE"
					fi
					ssh CTRL "psql -U postgres WebTool -c \"INSERT INTO monitor_server_cpu_affinity (environment, host_name, process_name, process_id, cpu_id) VALUES ('$ENVIRONMENT', '$HOST_NAME', '$server_new', ${pid_new}, ${FIX_CPU_ID_LISTS[$idx]});\""
				done
			elif [ ${#diff_2[@]} -gt 0 ]; then
				for idx in ${!diff_2[@]}; do
					server_old=${diff_2[$idx]}
					pid_old=$(ps -eo pid,pcpu,comm --sort=-pcpu | grep ${server_old} | awk '{print $1}')
					cpu_id=$($HOME/bin/get_specific_server_cpu_affinity ${server_old})
					
					server_new=${diff_1[$idx]}
					pid_new=$(ps -eo pid,pcpu,comm --sort=-pcpu | grep ${server_new} | awk '{print $1}')
					
					$HOME/bin/set_server_to_non_isolated_cpus ${server_old}
					taskset -cp ${cpu_id} ${pid_new}
					if [ "$HOST_NAME" == "TEST" -o "$HOST_NAME" == "SUB" -o "$HOST_NAME" == "SUBMIT" -o "$HOST_NAME" == "DATA" -o "$HOST_NAME" == "DLC" -o "$HOST_NAME" == "TIME1" -o "$HOST_NAME" == "MEDIA" ] ; then
						ENVIRONMENT="TEST"
					else
						ENVIRONMENT="LIVE"
					fi
					ssh CTRL "psql -U postgres WebTool -c \"INSERT INTO monitor_server_cpu_affinity (environment, host_name, process_name, process_id, cpu_id) VALUES ('$ENVIRONMENT', '$HOST_NAME', '$server_new', ${pid_new}, ${cpu_id});\""
				done 
			fi
		fi	
	else
		echo 'Not set isolcpus on grub and reboot'
	fi
else
	echo 'Not Enable parameter ${ENABLE_FIX_CPU_FOR_GAMESERVERS}.'
fi
