#! /usr/bin/env bash

TOOLBOXALMA="quay.io/toolbx-images/almalinux-toolbox"
TOOLBOXALPINE="quay.io/toolbx-images/alpine-toolbox"
TOOLBOXARCH="quay.io/toolbx/arch-toolbox"
TOOLBOXCENTOS="quay.io/toolbx-images/centos-toolbox"
TOOLBOXDEBIAN="quay.io/toolbx-images/debian-toolbox"
TOOLBOXFEDORA="quay.io/fedora/fedora-toolbox"
TOOLBOXGENTOO="docker.io/gentoo/stage3"
TOOLBOXOPENSUSE="quay.io/toolbx-images/opensuse-toolbox"
TOOLBOXRHEL="registry.access.redhat.com"
TOOLBOXUBUNTU="quay.io/toolbx/ubuntu-toolbox"


function f_help {
	echo ""
	echo "Usage:"
	echo " $0 subcommand [-d] [-r] [-l] [-h] cont-name"
	echo ""
	echo "Tool to create a podmain container you can use as a virtual machine."
	echo ""
	echo "Options :"
	echo "  -d		Distro"
	echo "  -r		Release"
	echo "  -p		Port redirection (8080:80) or multiport redirection (8080:80,8443:443)"
	echo "  -l		List distros available"
	echo "  -h		Help"
	echo "  cont-name	Name of your container"
	echo ""
	echo "Note:"
	echo "Rootfull Mode (root) : "
	echo "	- Container is in the podman default network. (Container has podman IP address)"
	echo "	- Full access to the container on all ports via container IP address from host."
	echo "Rootless Mode (user) : "
	echo "	- !! Container can't open <1024 ports !!"
	echo "	- Container is in host mode. Container has same IP than host. (Container has same IP than host)"
	echo "	- Container is in the podman default network if port redirection enabled. (Container has podman IP address)"
	# rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission denied
}

function f_list {
	echo "Supported distros :"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "+   \033[1m distro \033[0m   +                \033[1m release version \033[0m               +"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| alma         | 8 9 or latest                                  |"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| alpine       | 3.19 3.20 edge or latest                       |"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| arch         | latest                                         |"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| centos       | stream8 stream9 or latest                      |"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| debian       | 10 11 12 testing unstable or latest            |"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| fedora       | 39 40 41 rawhide or latest                     |"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| gentoo       | latest systemd                                 |"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| opensuse     | tumbleweed                                     |"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| rhel         | 8.10 9.3 9.4 ... (<major>.<minor>' format)     |"
	echo -e "+--------------+------------------------------------------------+"
	echo -e "| ubuntu       | 22.04 24.04 ... (YY.MM format)                 |"
	echo -e "+--------------+------------------------------------------------+"
}

TOOLBOXSUBCOMMAND="$1"
shift

while getopts ":d:r:p:lh" option; do
	case $option in
		d)
			option_d=true
			val_d=$OPTARG
		;;
		p)
			option_p=true
			val_p=$OPTARG
		;;
		r)
			option_r=true
			val_r=$OPTARG
		;;
		l)
			if [[ -n $option_d || -n $option_r ]]
			then
				echo "-l cannot be used with -d or -r"
				exit 1
			fi
			option_l=true
		;;
		h)
			f_help
			exit 0
		;;
		\?)
			echo "Invalid option: -$OPTARG" >&2
			f_help
			exit 1
		;;
		:)
			echo "-$OPTARG needs value" >&2
			f_help
			exit 1
		;;
	esac
done

shift $((OPTIND - 1))
TOOLBOXNAME="${!#}"
TETVM="$0"

if [[ $option_l == false && "$TETVM" = "$TOOLBOXNAME" ]]
then
	echo "You must specify a cont-name."
	f_help
	exit 1
fi

if [[ $TOOLBOXSUBCOMMAND = "create" ]]
then
	PODMANOPTS=""
	if [[ "$EUID" = 0 ]]
	then
		PODMANOPTS="--network=bridge"
		if [[ $option_p == true ]]
		then
			PODMANPORTS=$(echo "$val_p" | sed -e 's/,/ -p /g')
			PODMANOPTS="--network=bridge -p $PODMANPORTS "
		fi
	else
		PODMANOPTS="--network=host"
		if [[ $option_p == true ]]
		then
			PODMANPORTS=$(echo "$val_p" | sed -e 's/,/ -p /g')
			PODMANOPTS="--network=bridge -p $PODMANPORTS "
		fi
	fi

	if [[ $option_d == true && $option_r == true ]]
	then
		TOOLBOXDISTRO=$val_d
		TOOLBOXRELEASE=$val_r
		case $TOOLBOXDISTRO in
			alma)
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$TOOLBOXALMA:$TOOLBOXRELEASE" /sbin/init
				;;
			alpine)
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$TOOLBOXALPINE:$TOOLBOXRELEASE" /sbin/init
				;;
			arch)
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$TOOLBOXARCH:$TOOLBOXRELEASE" /sbin/init
				;;
			centos)
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$TOOLBOXCENTOS:$TOOLBOXRELEASE" /sbin/init
				;;
			debian)
				# EXPERIMENTAL, NEED CLEANING CODE
				# MAKE LOCALLY A DEBIAN IMAGE WITH SYSTEMD SUPPORT
				if ! podman images --format "{{.Repository}}:{{.Tag}}" | grep -q "localhost/tet-$TOOLBOXDISTRO-$TOOLBOXRELEASE"
				then
					echo -n "Generating a Debian image including systemd... Please wait "
					podman run -d --name tet_tmp_deb "$TOOLBOXDEBIAN:$TOOLBOXRELEASE" bash -c "apt-get update && apt-get install -y systemd init" &> /dev/null
					while [[ $(podman inspect --format '{{.State.Running}}' tet_tmp_deb) = "true" ]]
					do
						sleep 1
						echo -n "."
					done	
					podman commit tet_tmp_deb "tet-$TOOLBOXDISTRO-$TOOLBOXRELEASE" &> /dev/null
					podman stop tet_tmp_deb &> /dev/null
					podman rm tet_tmp_deb &> /dev/null
					echo ""
				fi
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "tet-$TOOLBOXDISTRO-$TOOLBOXRELEASE" /sbin/init
				;;
			fedora)
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$TOOLBOXFEDORA:$TOOLBOXRELEASE" /sbin/init
				;;
			gentoo)
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$TOOLBOXGENTOO:$TOOLBOXRELEASE" /sbin/init
				;;
			opensuse)
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$TOOLBOXOPENSUSE:$TOOLBOXRELEASE" /sbin/init
				;;
			rhel)
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$TOOLBOXRHEL/ubi${TOOLBOXRELEASE%%.*}/toolbox:$TOOLBOXRELEASE" /sbin/init
				;;
			ubuntu)
				podman create $PODMANOPTS --name "$TOOLBOXNAME" --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro "$TOOLBOXUBUNTU:$TOOLBOXRELEASE" /sbin/init
				;;
			*)
				echo "Unknown distro : $TOOLBOXDISTRO"
				f_list
				exit 1
				;;
		esac

	elif [[ $option_d == true || $option_r == true ]]
	then	
		echo "You must specify a distro (-d) AND a release version (-r)"
	elif [[ $option_l == true ]]
	then
		f_list
	else
		# No opt
		f_help
	fi
elif [[ $TOOLBOXSUBCOMMAND = "enter" ]]
then

	# Check if container isn't a toolbox. Refuse entering if it's a toolbox
	TOOLBOXNOTTOOLBOX=$(podman inspect --format '{{.Config.Hostname}}' "$TOOLBOXNAME")
	if [[ $TOOLBOXNOTTOOLBOX = "toolbx" ]]
	then
		echo -e "Container $TOOLBOXNAME is a toolbox. Please run : \e[1mtoolbox enter $TOOLBOXNAME\e[0m"
		exit 1
	fi

	# Chech if container started. If no, start before exec
	TOOLBOXSTATUS=$(podman inspect --format '{{.State.Running}}' "$TOOLBOXNAME")
	if [[ $TOOLBOXSTATUS != "true" ]]
	then
		podman start $TOOLBOXNAME &> /dev/null
	fi
	podman exec -it $TOOLBOXNAME /bin/bash
else
	# Wrong subcommand
	if [[ ! -z "$TOOLBOXSUBCOMMAND" ]]
	then
		echo "Unknown subcommand $TOOLBOXSUBCOMMAND"
	fi
	f_help
fi
