#!/bin/sh

# Copyright (c) 2017, Luca Pizzamiglio <pizzamig@FreeBSD.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
#   contributors may be used to endorse or promote products derived from
#   this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Force ifconfig into expected format
export IFCONFIG_FORMAT=addr:default

# Environment initialization and initial checks

# shellcheck disable=SC2034
_POT_VERSION=0.12.0
_POT_PATHNAME="$(realpath "$0")"
_POT_PREFIX="$(dirname "${_POT_PATHNAME}")"
_POT_INCLUDE="$( realpath "${_POT_PREFIX}/../share/pot")"
_POT_ETC="$( realpath "${_POT_PREFIX}/../etc/pot")"
if [ -d "${_POT_ETC}/flavours" ]; then
	_POT_FLAVOUR_DIR="$( realpath "${_POT_ETC}/flavours")"
else
	# shellcheck disable=SC2034
	_POT_FLAVOUR_DIR=
fi

if [ ! -d "${_POT_INCLUDE}" ]; then
	echo "Fatal error! Not able to find the subroutines directory as ${_POT_INCLUDE}!"
	exit 1
fi

# loading subroutines

if [ ! -r "${_POT_INCLUDE}/common.sh" ]; then
	echo "Fatal error! Not able to find common subroutines in ${_POT_INCLUDE}!"
	exit 1
fi
# shellcheck disable=SC1090
. "${_POT_INCLUDE}/common.sh"

if [ ! -r "${_POT_INCLUDE}/common-flv.sh" ]; then
	echo "Fatal error! Not able to find flavor subroutines in ${_POT_INCLUDE}!"
	exit 1
fi
# shellcheck disable=SC1090
. "${_POT_INCLUDE}/common-flv.sh"

if [ ! -r "${_POT_INCLUDE}/network.sh" ]; then
	echo "Fatal error! Not able to find network subroutines in ${_POT_INCLUDE}!"
	exit 1
fi
# shellcheck disable=SC1090
. "${_POT_INCLUDE}/network.sh"

# loading configuration
if [ -r "$_POT_ETC/pot.default.conf" ]; then
	# shellcheck disable=SC1090
	. "$_POT_ETC/pot.default.conf"
else
	_error "Fatal error! Not able to find default configuration file on $_POT_ETC"
	exit 1
fi

if [ -r "$_POT_ETC/pot.conf" ]; then
	# shellcheck disable=SC1090
	. "$_POT_ETC/pot.conf"
fi

usage() {
	cat << EOF
Usage: pot command [options]

Commands:
	help	-- Show help
	version -- Show the pot version
	config  -- Show pot framework configuration
	ls/list	-- List of the installed pots
	show	-- Show pot information
	info    -- Print minimal information on a pot
	top     -- Run the unix top in the pot
	ps      -- Show running pots
	init	-- Initialize the ZFS layout
	de-init	-- Deinstall pot from your system
	vnet-start -- Start the vnet configuration
	create-base	-- Create a new base image
	create-fscomp -- Create a new fs component
	create-private-bridge -- Create a new private bridge
	create -- Create a new pot (jail)
	clone -- Clone a pot creating a new one
	clone-fscomp - Clone a fscomp
	rename -- Rename a pot
	destroy -- Destroy a pot
	prune   -- Destroy not running prunable pots
	copy-in -- Copy a file or a directory into a pot
	mount-in -- Mount a directory, a zfs dataset or a fscomp into a pot
	add-dep -- Add a dependency
	set-rss -- Set a resource constraint
	get-rss -- Get the current resource usage
	set-cmd -- Set the command to start the pot
	set-env -- Set environment variabls inside a pot
	set-hosts -- Set etc/hosts entries inside a pot
	set-hook -- Set hook scripts for a pot
	set-attr -- Set a pot's attribute
	get-attr -- Get a pot's attribute
	export-ports -- Let export tcp ports
	start -- Start a jail (pot)
	stop -- Stop a jail (pot)
	term -- Start a terminal in a pot
	run -- Start and open a terminal in a pot
	snap/snapshot -- Take a snapshot of a pot
	rollback/revert -- Restore the last snapshot
	purge-snapshots -- Remove old/all snapshots
	export -- Export a pot to a file
	import -- Import a pot from a file or a URL
	prepare -- Import and prepare a pot - designed for jail orchestrator
	update-config -- Update the configuration of a pot
EOF
}

# shellcheck disable=SC2034
# variable initialization
_POT_VERBOSITY=1

# parsing command line subcommand
if [ $# -lt 1 ]; then
	usage
	exit 1
fi
CMD="$1"
shift

case "${CMD}" in
	ls)
		CMD=list
		;;
	rollback)
		CMD=revert
		;;
	snap)
		CMD=snapshot
		;;
	set-attr)
		CMD=set-attribute
		;;
	get-attr)
		CMD=get-attribute
		;;
esac

case "${CMD}" in
	help)
		if [ -n "$1" ]; then
			pot-cmd "${CMD}" "$1"
			exit 0
		else
			usage
			exit 0
		fi
		;;
	show|version|config|\
	list|info|ps|top|\
	init|de-init|vnet-start|\
	create-base|create-fscomp|create|\
	create-private-bridge|\
	copy-in|mount-in|prune|set-hook|\
	destroy|add-dep|set-rss|get-rss|set-cmd|set-env|set-hosts|\
	export|import|prepare|\
	export-ports|set-attribute|get-attribute|\
	start|stop|term|\
	rename|clone|clone-fscomp|promote|\
	snapshot|revert|purge-snapshots|update-config)
		pot-cmd "${CMD}" "$@"
		exit $?
		;;
	run)
		pot-cmd term -f "$@"
		exit $?
		;;
	*)
		usage
		exit 1
		;;
esac
