#!/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 --login
}

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    "Temporary 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 "You can retrieve the password for the \"root\""
	echo "user at any time with the command \"showpasswd\"."
	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

	if [ "$external_ip" == "N/A" ]; then
		return 1
	else
		echo $external_ip
	fi
}

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 "$@"
