#!/bin/bash
#
# Copyright (C) 2015-2016 Red Hat, Inc.
#
# This file is part of atomic-devmode.
#
# atomic-devmode is free software: you can redistribute it
# and/or modify it under the terms of the GNU Lesser General
# Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# atomic-devmode is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE.  See the GNU Lesser General Public License for
# more details.
#
# You should have received a copy of the GNU Lesser General
# Public License along with atomic-devmode. If not, see
# <http://www.gnu.org/licenses/>.

set -euo pipefail

main() {

	if [ $# -eq 0 ]; then
		rm -f /run/atomic-devmode-cockpit.rc
		tmux split-window -d -v -t devmode:main.0 "$0 bottom"
		tmux new-window -d -n terminal "$0 terminal"
		tmux new-window -d -n terminal "$0 terminal"
		exec $0 top
	fi

	# We trap SIGINT here so that if the user presses ^C (e.g. to exit
	# journalctl), the signal will kill the children but not us, so that we
	# reach the bash prompt.
	trap 'true' SIGINT

	# Let's set up the specific pane we were called for. NB: we turn off errexit
	# here before setting up the pane because if something does go wrong, it
	# would be more useful to keep the pane open to see the error output. The
	# downside is that we have to be extra careful in how we treat commands that
	# may fail.
	set +e
	${1}_pane

	# time to become a shell that the user can type in
	# NB: turn off (the rest of) strict mode so we act like a normal shell
	set +uo pipefail
	exec bash
}

top_pane() {

	echo    "Welcome to Atomic Developer Mode!"
	echo

	if [ ! -r /run/atomic-devmode-root ]; then
		echo "ERROR: Cannot read /run/atomic-devmode-root"
		return
	fi

	echo    "Password for root:  $(cat /run/atomic-devmode-root)"

	echo -n "IP address:         < waiting... > "

	ip=$(get_external_ip)
	if [ $? -ne 0 ]; then
		echo
		echo "ERROR: Could not retrieve IP."
		return
	fi

	echo -e "\rIP address:         $ip"

	echo -n "Cockpit console:    < downloading... > "

	while [ ! -f /run/atomic-devmode-cockpit.rc ]; do
		sleep 1
	done

	rc=$(cat /run/atomic-devmode-cockpit.rc)
	if [ "$rc" != 0 ]; then
		echo
		echo "ERROR: Could not start cockpit container."
		return
	fi

	echo -e "\rCockpit console:    https://$ip:9090/"
	echo

	echo "You can now log in the Cockpit console with"
	echo "the user \"root\" and the password above."
	echo

	echo "Use Ctrl+Space to change active pane."
	echo "Use Alt+1/2/3 to change active window."
	echo
}

get_external_ip() {

	wait_for_docker
	if [ $? -ne 0 ]; then
		return 1
	fi

	# get IP of docker bridge if present and running
	local docker_ip=
	if nmcli -t -f NAME,STATE con show | grep -q docker0:activated; then
		docker_ip=$(nmcli -t con show docker0 | grep ipv4.addresses:)
		docker_ip=${docker_ip#*:}
		docker_ip=${docker_ip%/*}
	fi

	# go through all IPs that are not docker and just pick the first one
	local external_ip="N/A"
	for ip in $(hostname -I); do
		if [ "$ip" != "$docker_ip" ]; then
			external_ip=$ip
			break
		fi
	done

	echo $external_ip
}

bottom_pane() {

	wait_for_docker
	if [ $? -ne 0 ]; then
		echo
		echo "ERROR: The docker service failed to start."
		return 1
	fi

	rc=0
	atomic run cockpit/ws || rc=$?
	echo $rc > /run/atomic-devmode-cockpit.rc
	journalctl -f
}

wait_for_docker() {

	# block until the docker service is running or failing
	while [[ $(systemctl show -p SubState docker.service) != *=running ]] && \
	      [[ $(systemctl show -p SubState docker.service) != *=failed ]]; do
		sleep 0.5
	done

	# exit with the service code
	systemctl status docker.service &> /dev/null
}

terminal_pane() {
	echo "Use Alt+1/2/3 to change active window."
	echo
}

main "$@"
