#!/bin/bash
#
# This script will remove an image, but first remove all of the child images 
# of that image so that we can proceed.
#
# There's no easy to do this without issuing a bunch of Docker commands, so here we are.
#

# Errors are fatal
set -e

#
# ANSI codes for printing out different colors.
#
RED="\033[0;31m"
GREEN="\033[0;32m"
NC="\033[0m"


#
# Check to see if the specified image exists.
# 
# If it does, something will be returned, if not, nothing will be returned.
#
function does_image_exist() {
	local IMAGE=$1
	RESULT=$(docker images -a | grep $IMAGE || true)
	echo $RESULT
}


#
# Get child images for the supplied argument.  Nothing is returned if none are found
#
function get_child_images() {
	local IMAGE=$1
	RESULT=$(docker images --filter since=${IMAGE} --quiet 2>/dev/null | sort | uniq | tr '\n' ' ')
	echo $RESULT
}


#
# Run our sanity checks.
#
function sanity_check() {

	local IMAGE=$1

	echo "# Verifying that image ${IMAGE} exists..."
	if test ! "$(does_image_exist ${IMAGE})"
	then
		echo "! "
		echo "! Sorry, image ${IMAGE} not found!"
		echo "! "
		return 1
	fi

} # End of sanity_check()


#
# Check for and remove stopped containers.
#
function remove_stopped_containers() {

	echo "# Checking for stopped containers..."
	local CONTAINERS=$(docker ps -a | grep Exit | awk '{print $1}' | tr '\n' ' ')
	if test "$CONTAINERS"
	then
		echo "# Removing the following stopped containers: ${CONTAINERS}"
		docker rm ${CONTAINERS}
	fi

} # End of remove_stopped_containers()


#
# Remove all tags from the supplied image.
#
function remove_tags() {

	local IMAGE=$1

	echo "# Checking image ${IMAGE} for tags that use it..."
	local TAGS=$(docker images | grep $IMAGE | awk '{print $1}' | sort | uniq | tr '\n' ' ')
	if test "${TAGS}"
	then
		echo "# Tags found to remove: ${TAGS}"
		docker rmi ${TAGS}
	fi

} # End of remove_tags()


#
# Remove an image if it exists.
#
function remove_image() {

	local IMAGE=$1
	
	printf "#${RED} Processing image ${IMAGE}...${NC}\n"
	remove_child_images $IMAGE

	printf "# ${GREEN}Removing image ${IMAGE}...${NC}\n"
	remove_tags $IMAGE

	if test "$(does_image_exist ${IMAGE})"
	then
		docker rmi $IMAGE
	fi

} # End of remove_image()


#
# Recursively remove all child images of an image.
#
function remove_child_images() {

	local MAIN_IMAGE=$1
	local IMAGE

	echo "# Checking for child images of ${MAIN_IMAGE}...."
	local IMAGES=$(get_child_images ${MAIN_IMAGE})
	#docker images --filter since=${MAIN_IMAGE} # Debugging

	if test ! "$IMAGES"
	then
		echo "# No child images of ${MAIN_IMAGE}, bailing out!"
		return 0
	fi

	printf "# ${RED}-> Found the following child images of ${MAIN_IMAGE}: ${NC}\n"
	echo "# ${IMAGES}"

	for IMAGE in $IMAGES
	do
		remove_image $IMAGE
	done

	printf "# ${GREEN}<- Done removing child images of ${MAIN_IMAGE}${NC}\n"

} # End of remove_child_images()


if test ! "$1"
then
	echo "! "
	echo "! Syntax: $0 docker_image_id"
	echo "! "
	exit 1
fi

MAIN_IMAGE=$1

sanity_check $MAIN_IMAGE
remove_stopped_containers
remove_image $MAIN_IMAGE

printf "# ${GREEN}Done removing image ${MAIN_IMAGE} and its children!${NC}\n"