#!/bin/sh

. /usr/share/libubox/jshn.sh
. /lib/sshmngr/backend.sh

add_server_name()
{
	local server_sec="${1}"

	config_get_bool enable "${server_sec}" enable 0
	if [ "${enable}" -eq 0 ]; then
		return
	fi

	server_names="${server_names} ${server_sec}"
}

get_all_servers()
{
	server_names=""

	local backend_config="$CONFIG"
	local server_section_type="$CONFIG"

	config_load $backend_config
	config_foreach add_server_name $server_section_type

	echo "${server_names}"
}

get_pid()
{
	local server_name="$1"
	local pid_file="$(get_pid_file "$server_name")"
	local server_pid=0

	# if proper file exists
	if [ -f "${pid_file}" ] && [ -s "${pid_file}" ]; then
		server_pid="$(cat "${pid_file}")"
	fi

	echo "$server_pid"
}

case "$1" in
	list)
		echo '{ "dump" : {"server_name":"string"}, "kill_session" : {"session_pid":"string","server_name":"string"}, "list_keys" : {}, "add_pubkey" : {"current_key":"string","new_key":"string"}, "remove_pubkey" : {"key":"string"} }'
	;;
	call)
		case "$2" in
			dump)
				read -r input
				json_load "${input}"
				json_get_var server_name "server_name"
				json_cleanup

				if [ -z "$server_name" ]; then
					servers="$(get_all_servers)"
				else
					servers="$server_name"
				fi

				json_init

				for server in $servers; do
					json_add_object "$server"

					pid_file="$(get_pid_file "$server")"
					server_pid="$(get_pid "$server")"

					if [ "$server_pid" -eq 0 ]; then
						break
					fi

					# get all current sessions
					session_pids="$(get_session_pids "$pid_file")"

					json_add_string "pid" "$server_pid"
					json_add_array "sessions"

					for session_pid in $session_pids; do
						# if pid equals server pid then skip
						[ "$session_pid" -eq "$server_pid" ] && continue

						network_info="$(get_network_info "$session_pid" "$server_pid")"
						if [ $? -eq 0 ]; then
							ip=$(echo "$network_info" | cut -d' ' -f1)
							port=$(echo "$network_info" | cut -d' ' -f2)

							json_add_object
							json_add_string "ip" "$ip"
							json_add_string "port" "$port"
							json_add_string "pid" "$session_pid"
							json_close_object
						fi
					done

					json_close_array
					json_close_object
				done

				json_dump
			;;

			kill_session)
				read -r input
				json_load "${input}"
				json_get_var session_pid "session_pid"
				json_get_var server_name "server_name"
				json_cleanup

				if [ "$session_pid" -gt 0 ]; then
					kill -15 "$session_pid"
				else
					if [ -z "$server_name" ]; then
						echo '{}'
						exit 0
					fi

					# if server_name is present
					# get all current sessions
					pid_file="$(get_pid_file "$server_name")"
					server_pid="$(get_pid "$server_name")"

					if [ "$server_pid" -eq 0 ]; then
						echo '{}'
						exit 0
					fi

					# get all current sessions
					session_pids="$(get_session_pids "$pid_file")"

					for session_pid in $session_pids; do
						# if pid equals server pid then skip
						[ "$session_pid" -eq "$server_pid" ] && continue

						# get this session's ppid
						session_ppid="$(grep PPid /proc/$session_pid/status 2>/dev/null | awk '{print $2}')"
						[ -z "$session_ppid" ] && continue

						# get the parent of the parent (the grandparent)
						grandparent_pid="$(grep PPid /proc/$session_ppid/status 2>/dev/null | awk '{print $2}')"

						# if session's parent or grandparent is this server
						if [ "$session_ppid" -eq "$server_pid" ] || { [ -n "$grandparent_pid" ] && [ "$grandparent_pid" -eq "$server_pid" ]; }; then
							kill -15 "$session_pid"
						fi
					done
				fi
				echo '{}'
			;;

			list_keys)
				# remove empty lines from file
				sed -i '/^[[:space:]]*$/d' "$KEY_FILE"

				json_init
				json_add_array "keys"

				while read line; do
					json_add_string "key" "${line}"
				done < "$KEY_FILE"

				json_close_array
				json_dump
			;;

			add_pubkey)
				read -r input
				json_load "${input}"
				json_get_var current_key "current_key"
				json_get_var new_key "new_key"
				json_cleanup

				if [ -n "${new_key}" ]; then
					if [ -n "${current_key}" ]; then
						rm -rf TEMP_KEY_FILE
						touch TEMP_KEY_FILE

						# sed -i "s/${current_key}/${new_key}/g" ${KEY_FILE}
						# sed is not advisable because the separator ("/") or anything else
						# can be present in the string
						while read line; do
							if [ "${line}" == "${current_key}" ]; then
								echo "${new_key}" >> TEMP_KEY_FILE
							else
								echo "${line}" >> TEMP_KEY_FILE
							fi
						done < "$KEY_FILE"

						mv TEMP_KEY_FILE "$KEY_FILE"
					else
						echo "${new_key}" >> ${KEY_FILE}
					fi
				fi
				echo '{}'
			;;

			remove_pubkey)
				read -r input
				json_load "${input}"
				json_get_var key "key"
				json_cleanup


				if  [ -n "${key}" ]; then
					rm -rf TEMP_KEY_FILE
					touch TEMP_KEY_FILE

					# sed -i "/${key}/d" ${KEY_FILE}
					# sed -i "s/${current_key}/${new_key}/g" ${KEY_FILE}
					# sed is not advisable because the separator ("/") or anything else
					# can be present in the string
					while read line; do
						if [ "${line}" != "${key}" ]; then
							echo "${line}" >> TEMP_KEY_FILE
						fi
					done < "$KEY_FILE"

					mv TEMP_KEY_FILE "$KEY_FILE"
				fi
				echo '{}'
			;;
		esac
	;;
esac

