#!/bin/bash
#
# Like what you see? Join us!
# https://www.univention.com/about-us/careers/vacancies/
#
# SPDX-FileCopyrightText: 2015-2025 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only

### BEGIN INIT INFO
# Provides:          @%@APPID@%@_Container
# Required-Start:    $remote_fs $syslog docker
# Required-Stop:     $remote_fs $syslog docker
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start the Container for @%@APPID@%@
# Description:       Start the Docker container
#                    for @%@APPID@%@
### END INIT INFO

set -e

# Get lsb functions
. /lib/lsb/init-functions

# load UCS docker functions
. /usr/lib/univention-docker/univention-docker_lib.sh

AUTOSTART_LIB_PATH=/usr/share/univention-config-registry/init-autostart.lib

app_container_init_script_name=$(basename "$0")

if [ "${app_container_init_script_name:0:1}" = "S" ] || [ "${app_container_init_script_name:0:1}" = "K" ]; then
	# started by init switching runlevel, strip first 3 characters
	app_container_init_script_name="${app_container_init_script_name:3}"
fi
app_name="${app_container_init_script_name#docker-app-}"	## cut away the prefix
app_name="${app_name#container-init-script}"	## cut away the extended prefix

if [ -z "$app_name" ]; then
	echo "This is a generic SysV init script for docker app containers."
	echo "To do anything useful it needs to be copied to a file named"
	echo "according to this scheme:"
	echo -e "\tdocker-app-<APP_AME>"
	echo "or"
	echo -e "\tdocker-app-container-init-script-<APP_NAME>"
	exit 1
fi
app_name="${app_name#-}"	## cut away the remaining leading dash

## Early check for sane usage:
case "$1" in
	start|stop|restart|crestart|kill|status)
		if ! docker_is_running; then
			log_failure_msg "Docker not running"
			exit 1
		else
			requested_action="$1"
		fi
		;;
	*)
		log_success_msg "Usage: init_script_name {start|stop|restart|crestart|kill|status}"
		exit 1
esac

## Get the relevant UCR variables
AUTOSTART_VARIABLE="$app_name/autostart"
ucr_container_key="$(univention-app get $app_name ucr_container_key --values-only)"
container_uuid=$(ucr get "$ucr_container_key")

if [ -z "$container_uuid" ]; then
	echo "Don't know which container to $requested_action."
	echo "The UCR variable $ucr_container_key is not set."
	exit 1
fi

# Include defaults if available
DEFAULTS="/etc/default/$app_container_init_script_name"
[ -r "$DEFAULTS" ] && . "$DEFAULTS"

## Define functions to be used below
create_container_from_image() {
	local app_image_name
	app_image_name="$1"

	echo "This script cannot create a container from an image."
	echo "It can just stop/restart existing containers."
	return 1
}

container_run_state() {
	local container_uuid
	container_uuid="$1"

	run_state=$(docker inspect -f "{{.State.Running}}" "$container_uuid")
	if [ $? -ne 0 ]; then
		echo "invalid"
		echo "Failed to determine container state. Probably it doesn't exist." 1>&2
		return 1
	fi

	if [ "$run_state" = "true" ]; then
		echo "running"
	elif [ "$run_state" = "false" ]; then
		echo "stopped"
	fi
}

start_container() {
	local container_uuid
	container_uuid="$1"

	run_state=$(container_run_state "$container_uuid") || create_container_from_image "$app_name" || return $?
	if [ "$run_state" = "running" ]; then
		echo "Container is already running"
		return 0
	fi

	log_begin_msg "Starting $app_name Container $container_uuid ..."
	_do_restart_container "$run_state" "$container_uuid"
	log_end_msg $?
}

restart_container() {
	local container_uuid
	container_uuid="$1"

	run_state=$(container_run_state "$container_uuid") || return $?

	log_begin_msg "Restarting $app_name Container $container_uuid ..."
	_do_restart_container "$run_state" "$container_uuid"
	log_end_msg $?
}

crestart_container() {
	local container_uuid
	container_uuid="$1"

	run_state=$(container_run_state "$container_uuid") || return $?
	if [ "$run_state" != "running" ]; then
		echo "Container not running, skipping crestart."
		return 0
	fi

	log_begin_msg "Restarting $app_name Container $container_uuid ..."
	_do_restart_container "$run_state" "$container_uuid"
	log_end_msg $?
}

_do_restart_container() {
	local run_state
	run_state="$1"

	local container_uuid
	container_uuid="$2"

	if [ "$run_state" = "running" ]; then
		exec_halt_inside_container "$container_uuid"
		wait_for_containers_inner_shutdown "$container_uuid" 60
	fi

	uuid=$(docker restart --time=0 "$container_uuid")
	local ip="$(docker inspect --format={{.NetworkSettings.IPAddress}} "$uuid")"
	local ucr_key="$(univention-app get $app_name ucr_ip_key --values-only)"
	ucr set "${ucr_key}=${ip}" >/dev/null
}

stop_container() {
	local container_uuid
	local short_container_uuid
	container_uuid="$1"

	run_state=$(container_run_state "$container_uuid") || return $?
	if [ "$run_state" = "stopped" ]; then
		echo "Container not running, skipping stop."
		return 0
	fi

	log_begin_msg "Stopping $app_name Container $container_uuid ..."
	short_container_uuid="${container_uuid:0:12}"
	output=$(shutdown_containers "$short_container_uuid")
	log_end_msg $?
	if [ "$output" != " $short_container_uuid" ]; then
		echo -n "$output"
	fi
	local ucr_key="$(univention-app get $app_name ucr_ip_key --values-only)"
	ucr unset "${ucr_key}" >/dev/null
}

kill_container() {
	local container_uuid
	container_uuid="$1"

	run_state=$(container_run_state "$container_uuid") || return $?
	if [ "$run_state" = "stopped" ]; then
		echo "Container not running."
		## try to kill anyway
		# return 0
	fi

	log_begin_msg "Killing $app_name Container $container_uuid ..."
	output=$(docker kill "$container_uuid")
	log_end_msg $?
	if [ "$output" != "$container_uuid" ]; then
		echo "$output"
	fi
}

## Ok, action:
case "$requested_action" in
	start)
		# check UCR autostart setting
		if [ -f "$AUTOSTART_LIB_PATH" ]; then
			. "$AUTOSTART_LIB_PATH"
			check_autostart "$app_name" "$AUTOSTART_VARIABLE"
		fi
		start_container "$container_uuid"
		;;
	stop)
		stop_container "$container_uuid"
		;;
	restart)
		# check UCR autostart setting
		if [ -f "$AUTOSTART_LIB_PATH" ]; then
			. "$AUTOSTART_LIB_PATH"
			check_autostart "$app_name" "$AUTOSTART_VARIABLE"
		fi
		restart_container "$container_uuid"
		;;
	crestart)
		# check UCR autostart setting
		if [ -f "$AUTOSTART_LIB_PATH" ]; then
			. "$AUTOSTART_LIB_PATH"
			check_autostart "$app_name" "$AUTOSTART_VARIABLE"
		fi
		crestart_container "$container_uuid"
		;;
	kill)
		kill_container "$container_uuid"
		;;
	status)
		container_run_state "$container_uuid"
		;;
	*)
		log_success_msg "Usage: init_script_name {start|stop|restart|crestart|kill|status}"
		exit 1
esac
