#!/bin/bash

user=$1
pass_file=$2
host=$3
deployment_id=$4
agent_server=$5
agent_id=$6
backend_api=$7
agent_hub_uri=$8
ssh_ports=$9
platform_launcher_abs_path=${10}
rmq_client=${11}
rmq_client_config=${12}

Write_Log "Windows platform script started"

platform_root=$(dirname "$platform_launcher_abs_path")
ca_root="$agent_folder/ca"
bootstrap_script="$platform_root/package/bootstrap.ps1"
package_dir="$platform_root/package/pkg"
service_stub_dir="$platform_root/service_stub"
rnd=$(echo $RANDOM | md5sum | head -c 6)
win_pass_file=$(echo "$pass_file" | sed --expression 's/\/tmp\//%temp%\\/g')


ssh_enabled_port=0
for port in $ssh_ports
do
	Test_Port "$host" "$port"
	ret_port=$?
	if [[ $ret_port == 0 ]]
	then
		ssh_enabled_port=$port
		break
	fi
done

if [[ $ssh_enabled_port != 0 ]]
then
	Write_Log "SSH enabled on [$ssh_enabled_port] port. Proceed with SSH approach"
	# Copy detected script to the target machine and start
	tmp_dir="%temp%\\colibri-$rnd"
	Write_Log "Create an empty temp folder for bootstrap"
	{ out_mkdir=$( (Invoke_SSH_Command "$user" "$pass_file" "$host" "$ssh_enabled_port" "cmd /c mkdir \"$tmp_dir\"") 2>&1 1>&3-) ;} 3>&1
	retcode=$?
	if [ $retcode != 0 ]
	then
		message="SSH. Unable to create temp folder [$tmp_dir] with output [$out_mkdir]"
		Write_Log "$message" "ERROR"
		timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
		status="Error"
		validation_report="$message"
		Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"
		exit 1
	fi

	Write_Log "Upload bootstrap"
	{ out_upload=$( (sshpass -f "$pass_file" scp -O -r -o "StrictHostKeyChecking=no" -P "$ssh_enabled_port" "$ca_root" "$bootstrap_script" "$package_dir" "$user@$host:$tmp_dir")  2>&1 1>&3-) ;} 3>&1
	retcode=$?
	if [ $retcode != 0 ]
	then
		message="SSH. Unable to upload bootstrap: [$out_upload]"
		Write_Log "$message" "ERROR"
		timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
		status="Error"
		validation_report="$message"
		Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"
		exit 2
	fi

	Write_Log "Start bootstrap"
	{ out_start=$( (Invoke_SSH_Command "$user" "$pass_file" "$host" "$ssh_enabled_port" "powershell -ExecutionPolicy ByPass -f \"${tmp_dir}\\bootstrap.ps1\" -deployment_id \"${deployment_id}\" -agent_server \"${agent_server}\" -signalr_server \"${agent_hub_uri}\" -agent_id \"${agent_id}\"")  2>&1 1>&3-) ;} 3>&1
	retcode=$?
	if [ $retcode != 0 ]
	then
		message="SSH. Error during bootstrap start: [$out_start]"
		Write_Log "$message" "ERROR"
		timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
		status="Error"
		validation_report="$message"
		Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"
		exit 3
	fi

	Write_Log "Clean up a temp folder for bootstrap"
	{ out_rm=$( (Invoke_SSH_Command "$user" "$pass_file" "$host" "$ssh_enabled_port" "cmd /c if exist \"$tmp_dir\" rd /s /q \"$tmp_dir\"")  2>&1 1>&3-) ;} 3>&1
	retcode=$?
	if [ $retcode != 0 ]
	then
		message="SSH. Unable to remove temp folder [$tmp] with output [$out_rm]"
		Write_Log "$message" "ERROR"
		timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
		status="Error"
		validation_report="$message"
		Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"
		exit 4
	fi

	Write_Log "Clean up a password file"
	{ out_rm_pw=$( (Invoke_SSH_Command "$user" "$pass_file" "$host" "$ssh_enabled_port" "cmd /c if exist \"$win_pass_file\" rd /s /q \"$win_pass_file\"")  2>&1 1>&3-) ;} 3>&1
	retcode=$?
	if [ $retcode != 0 ]
	then
		message="SSH. Unable to remove temp folder [$tmp] with output [$out_rm_pw]"
		Write_Log "$message" "ERROR"
		timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
		status="Error"
		validation_report="$message"
		Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"
		exit 4
	fi
else
	wmi_test_output=$(Test_RPC "$user" "$pass_file" "$host")  
	wmi_test_result=$?
	if [[ $wmi_test_result == 0 ]]
	then
		Write_Log "WMI enabled. Proceed with WMI approach"
		{ out_test_admin_share=$( (Test_Admin_Share "$user" "$pass_file" "$host") 2>&1 1>&3-) ;} 3>&1
		ret_test_admin_share=$?
		if [ $ret_test_admin_share -ne 0 ]
		then
			message="WMI. Unable to access admin share C$ on target device. Stop script"
			Write_Log "$message. Error details: [$out_test_admin_share]" "ERROR"
			timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
			status="Error"
			validation_report="$message"
			Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"
			exit 5
		fi
		Write_Log "Admin share available, proceed..."

		Write_Log "Upload bootstrap"
		random_name="colibri-$rnd"
		mount_point="/mnt/$random_name"
		tmp_dir_linux="$mount_point/ProgramData/$random_name"
		tmp_dir_win="C:\\ProgramData\\$random_name"
		agent_root_linux="$mount_point/ProgramData/colibri"

		Write_Log "Split user and domain"
		user_name=$user
		# shellcheck disable=SC1003
		if echo "$user" | grep -q '\\'
			then
			domain=$(echo "$user" | sed -En 's/(.*)\\(.*)/\1/p')
			user_name=$(echo "$user" | sed -En 's/(.*)\\(.*)/\2/p')
		fi

		Write_Log "Make dir for mount point"
		if [ ! -d "$mount_point" ]
		then
			mkdir "$mount_point" > /dev/null
		fi

		Write_Log "Mount admin share to [$mount_point]"
		tmp_store="/tmp/$random_name"
		printf 'user=%s\npassword=%s\ndomain=%s' "$user_name" "$(cat "$pass_file")" "$domain" > "$tmp_store"
		{ out_mount_admin_share=$( (mount -t cifs -o credentials="$tmp_store" "//$host/C\$" "$mount_point" -vvv) 2>&1 1>&3-) ;} 3>&1
		ret_mount_admin_share=$?
		rm -f "$tmp_store"

		if [ $ret_mount_admin_share -ne 0 ]
		then
			message="WMI. Unable to mount [//$host/C$] to [$mount_point]: [$out_mount_admin_share]"
			Write_Log "$message" "ERROR"
			timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
			status="Error"
			validation_report="$message"
			Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"
			exit 6
		fi

		Write_Log "Remove leftovers from previous installations"
		for old_folder in "$mount_point"/ProgramData/colibri-*
		do
			Write_Log "Remove old folder $old_folder"
			rm -rf "$old_folder"
		done

		Write_Log "Make temp dir for bootstrap"
		if [ ! -d "$tmp_dir_linux" ]
		then
			mkdir "$tmp_dir_linux" > /dev/null
		fi

		Write_Log "Make dir for agent root"
		if [ ! -d "$agent_root_linux" ]
		then
			mkdir "$agent_root_linux" > /dev/null
		fi

		Write_Log "Upload bootstrap files to the target device:"
		Write_Log "- $bootstrap_script"
		Write_Log "- $package_dir"
		Write_Log "- $ca_root"
		Write_Log "Temp mountpoint: $tmp_dir_linux"
		cp "$bootstrap_script" "$tmp_dir_linux/" > /dev/null
		cp -r "$package_dir" "$tmp_dir_linux/" > /dev/null
		cp -r "$ca_root" "$tmp_dir_linux/" > /dev/null

		Write_Log "Upload Colibri Install Service"
		Write_Log "- $service_stub_dir"
		cp -r "$service_stub_dir" "$agent_root_linux"
		
		Write_Log "Prepare install command in $agent_root_linux/service_stub/command.csv"
		echo "path,deployment_id,agent_server,signalr_server,agent_id,Overwrite" > "$agent_root_linux/service_stub/command.csv"
		echo "${tmp_dir_win}\\bootstrap.ps1,$deployment_id,$agent_server,$agent_hub_uri,$agent_id,#switch#" >> "$agent_root_linux/service_stub/command.csv"
		[ -f "$agent_root_linux/service_stub/command.csv" ] || Write_Log "File [$agent_root_linux/service_stub/command.csv] not found"

		Write_Log "Start bootstrap"
		Write_Log " - Check if RPC Service already exists"
		Manage_RPC_Service "$user" "$pass_file" "$host" "delete" > /dev/null 2>&1
		ret_service_remove=$?
		if [ $ret_service_remove -eq 0 ]; then 
			Write_Log " - Service detected and removed"
			Write_Log " - Wait for 10 sec to complete Service removal"
			sleep 10
		fi
		Write_Log " - Create RPC Service"
		{ out_create=$( (Create_RPC_Service "$user" "$pass_file" "$host") 2>&1 1>&3-) ;} 3>&1
		ret_service_create=$?
		if [ $ret_service_create -ne 0 ]
		then
			message="WMI. Error during creation of RPC Service: [$out_create]"
			Write_Log "$message" "ERROR"
			timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
			status="Error"
			validation_report="$message"
			Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"

			Write_Log "Remove temp folder on a client"
			if [ -d "$tmp_dir_linux" ]
			then
				rm -rf "$tmp_dir_linux" > /dev/null
			fi

			Write_Log "Remove Service_Stub"
			if [ -d "$agent_root_linux/service_stub" ]
			then
				rm -rf "$agent_root_linux/service_stub" > /dev/null
			fi
			
			Write_Log "Unmount temp folder"
			umount "$mount_point" > /dev/null 2>&1

			Write_Log "Remove temp mountpoint"
			if [ -d "$mount_point" ]
			then
				rmdir "$mount_point" > /dev/null
			fi

			exit 70
		fi

		Write_Log " - Wait for 10 sec to complete Service creation"
		sleep 10

		Write_Log " - Start RPC Service"
		{ out_start=$( (Manage_RPC_Service "$user" "$pass_file" "$host" "start") 2>&1 1>&3-) ;} 3>&1
		ret_service_start=$?
		if [ $ret_service_start != 0 ]
		then
			message="WMI. Error during starting of RPC Service: \\\nReturn code: [$ret_service_start]\\\n Output: [$out_start]"
			Write_Log "$message" "ERROR"
			timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
			status="Error"
			validation_report="$message"
			Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"

			Write_Log "Remove temp folder on a client"
			if [ -d "$tmp_dir_linux" ]
			then
				rm -rf "$tmp_dir_linux" > /dev/null
			fi

			Write_Log "Remove Service_Stub"
			if [ -d "$agent_root_linux/service_stub" ]
			then
				rm -rf "$agent_root_linux/service_stub" > /dev/null
			fi

			Write_Log "Unmount temp folder"
			umount "$mount_point" > /dev/null 2>&1

			Write_Log "Remove temp mountpoint"
			if [ -d "$mount_point" ]
			then
					rmdir "$mount_point" > /dev/null
			fi

			exit 71
		fi

		Write_Log " - Wait for 10 sec to init bootstrap script"
		sleep 10

		Write_Log " - Stop RPC Service"
		{ out_stop=$( (Manage_RPC_Service "$user" "$pass_file" "$host" "stop") 2>&1 1>&3-) ;} 3>&1
		ret_service_stop=$?
		if [ $ret_service_stop -ne 0 ]; then
			Write_Log "WMI. The RPC Service is not stopped: \\\nReturn code: [$ret_service_stop]\\\n Output: [$out_stop]" "WARNING"
		fi

		Write_Log " - Wait for 10 sec to complete service stop process"
		sleep 10

		Write_Log " - Remove RPC Service"
		{ out_remove=$( (Manage_RPC_Service "$user" "$pass_file" "$host" "delete") 2>&1 1>&3-) ;} 3>&1
		ret_service_remove=$?
		if [ $ret_service_remove -ne 0 ]
		then
			message="WMI. Error during removing of RPC Service: [$out_remove]"
			Write_Log "$message" "ERROR"
			timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
			status="Error"
			validation_report="$message"
			Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"

			Write_Log "Remove temp folder on a client"
			if [ -d "$tmp_dir_linux" ]
			then
				rm -rf "$tmp_dir_linux" > /dev/null
			fi

			Write_Log "Remove Service_Stub"
			if [ -d "$agent_root_linux/service_stub" ]
			then
				rm -rf "$agent_root_linux/service_stub" > /dev/null
			fi

			Write_Log "Unmount temp folder"
			umount "$mount_point" > /dev/null 2>&1

			Write_Log "Remove temp mountpoint"
			if [ -d "$mount_point" ]
			then
					rmdir "$mount_point" > /dev/null
			fi

			exit 73
		fi

		Write_Log "Remove Service_Stub"
		if [ -d "$agent_root_linux/service_stub" ]
		then
			rm -rf "$agent_root_linux/service_stub" > /dev/null
		fi

		Write_Log "Installation in progress..."
		wait_iteration_time_sec=5
		iteration_count=1
		total_iterations=120 # 10 minutes timeout
		total_sec=$((total_iterations * wait_iteration_time_sec))
		flag_file="$tmp_dir_linux/pkg"
		while [[ $iteration_count -lt $total_iterations && -d "$flag_file" ]]
		do
			if [ -f "$tmp_dir_linux/error.log" ]
			then
				break
			fi
			iteration_count=$((iteration_count + 1))
			sleep 5
		done
		if [ $iteration_count -eq $total_iterations ]
		then
			message="WMI. Installation did not complete in $total_sec seconds. Check the client device"
			Write_Log "$message" "ERROR"
			timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
			status="Error"
			validation_report="$message"
			Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"

			Write_Log "Unmount temp folder"
			umount "$mount_point" > /dev/null 2>&1

			Write_Log "Remove temp mountpoint"
			if [ -d "$mount_point" ]
			then
				rmdir "$mount_point" > /dev/null
			fi

			exit 8
		fi

		if [ -f "$tmp_dir_linux/error.log" ]
		then
			Write_Log "Collect Error details:"
			output=$(cat "$tmp_dir_linux"/error.log)
			Write_Log "\n$output"
			message="WMI. Installation on a client complete with errors. Check the deployment log for this device"
			Write_Log "$message" "ERROR"
			timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
			status="Error"
			validation_report="$message"
			Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"

			Write_Log "Clean up a temp folder for bootstrap"
			Write_Log "Remove temp folder on a client"
			if [ -d "$tmp_dir_linux" ]
			then
				rm -rf "$tmp_dir_linux" > /dev/null
			fi

			Write_Log "Unmount temp folder"
			umount "$mount_point" > /dev/null 2>&1

			Write_Log "Remove temp mountpoint"
			if [ -d "$mount_point" ]
			then
				rmdir "$mount_point" > /dev/null
			fi

			exit 9
		fi

		if [ -f "$tmp_dir_linux/output.log" ]
		then
			Write_Log "Collect Output:"
			output=$(cat "$tmp_dir_linux"/output.log)
			Write_Log "\n$output"
			Write_Log "Agent successfully installed. Waiting for configuration"
		fi

		Write_Log "Clean up a temp folder for bootstrap"
		Write_Log "Remove temp folder on a client"
		if [ -d "$tmp_dir_linux" ]
		then
			rm -rf "$tmp_dir_linux" > /dev/null
		fi

		Write_Log "Unmount temp folder"
		umount "$mount_point" > /dev/null 2>&1

		Write_Log "Remove temp mountpoint"
		if [ -d "$mount_point" ]
		then
			rmdir "$mount_point" > /dev/null
		fi
	else
		message="WMI Disabled"
		Write_Log "$message. Error details: [$wmi_test_output]" "ERROR"
		timestamp=$(date -Ins | sed -E 's/(.*),([0-9]{7}).*(\+|-.*)/\1.\2\3/')
		status="Error"
		validation_report="$message"
		Send_Deployment_Message "$rmq_client" "$rmq_client_config" "$agent_id" "$deployment_id" "$timestamp" "$status" "$validation_report"
		exit 10
	fi
fi
