#!/bin/bash
set -eo pipefail

trap cleanup EXIT

# Defaults
REGISTRY=registry.redhat.io
IMAGE=rhel8/support-tools
TOOLBOX_NAME=toolbox-"${USER}"
TOOLBOXRC="${HOME}"/.toolboxrc

setup() {
    # Allow user overrides
    if [ -f "${TOOLBOXRC}" ]; then
        echo ".toolboxrc file detected, overriding defaults..."
        source "${TOOLBOXRC}"
    fi
    TOOLBOX_IMAGE="${REGISTRY}"/"${IMAGE}"
}

run() {
    if ! image_exists; then
        image_pull
    fi

    local runlabel=$(image_runlabel)
    if ! container_exists; then
        echo "Spawning a container '$TOOLBOX_NAME' with image '$TOOLBOX_IMAGE'"
        if [[ -z "$runlabel" ]]; then
            container_create
        else
            echo "Detected RUN label in the container image. Using that as the default..."
            container_runlabel
            return
        fi
    else
        echo "Container '$TOOLBOX_NAME' already exists. Trying to start..."
        echo "(To remove the container and start with a fresh toolbox, run: sudo podman rm '$TOOLBOX_NAME')"
    fi

    local state=$(container_state)
    if [[ "$state" == configured ]] || [[ "$state" == exited ]] || [[ "$state" == stopped ]]; then
        container_start
    elif [[ "$state" != running ]]; then
        echo "Container '$TOOLBOX_NAME' in unknown state: '$state'"
        return 1
    fi

    echo "Container started successfully. To exit, type 'exit'."
    container_exec "$@"
}

cleanup() {
    sudo podman stop "$TOOLBOX_NAME" &>/dev/null
}

container_exists() {
    sudo podman inspect "$TOOLBOX_NAME" &>/dev/null
}

container_state() {
    sudo podman inspect "$TOOLBOX_NAME" --format '{{.State.Status}}'
}

image_exists() {
    sudo podman inspect "$TOOLBOX_IMAGE" &>/dev/null
}

image_runlabel() {
    sudo podman container runlabel --display RUN "$TOOLBOX_IMAGE"
}

image_pull() {
    if ! sudo --preserve-env podman pull --authfile /var/lib/kubelet/config.json "$TOOLBOX_IMAGE"; then
        read -r -p "Would you like to manually authenticate to registry: '${REGISTRY}' and try again? [y/N] "

        if [[ $REPLY =~ ^([Yy][Ee][Ss]|[Yy])+$ ]]; then
            sudo --preserve-env podman login "${REGISTRY}"
            sudo --preserve-env podman pull "$TOOLBOX_IMAGE"
        else
            echo "Exiting..."
            exit 1
        fi
    fi
}

container_create() {
    if ! sudo podman create \
                 --hostname toolbox \
                 --name "$TOOLBOX_NAME" \
                 --network host \
                 --privileged \
                 --security-opt label=disable \
                 --tty \
                 --volume /:/media/root:rslave \
                 "$TOOLBOX_IMAGE" 2>&1; then
        echo "$0: failed to create container '$TOOLBOX_NAME'"
        exit 1
    fi
}

container_start() {
    if ! sudo podman start "$TOOLBOX_NAME" 2>&1; then
        echo "$0: failed to start container '$TOOLBOX_NAME'"
        exit 1
    fi
}

container_runlabel() {
    if ! sudo podman container runlabel --name "$TOOLBOX_NAME" RUN "$TOOLBOX_IMAGE" 2>&1; then
        echo "$0: failed to runlabel on image '$TOOLBOX_IMAGE'"
        exit 1
    fi
}

container_exec() {
    sudo podman exec \
            --env LANG="$LANG" \
            --env TERM="$TERM" \
            --tty \
            --interactive \
            "$TOOLBOX_NAME" \
            "$@"
}

show_help() {
    echo "USAGE: toolbox [-h/--help] [command]
toolbox is a small script that launches a container to let you bring in your favorite debugging or admin tools.
The toolbox container is a pet container and will be restarted on following runs.
To remove the container and start fresh, do sudo podman rm ${TOOLBOX_NAME}.

Options:
  -h/--help: Shows this help message

You may override the following variables by setting them in ${TOOLBOXRC}:
- REGISTRY: The registry to pull from. Default: $REGISTRY
- IMAGE: The image and tag from the registry to pull. Default: $IMAGE
- TOOLBOX_NAME: The name to use for the local container. Default: $TOOLBOX_NAME

Example toolboxrc:
REGISTRY=my.special.registry.example.com
IMAGE=debug:latest
TOOLBOX_NAME=special-debug-container"
}

main() {
    # Execute setup first so we get proper variables
    setup
    # If we are passed a help switch, show help and exit
    if [[ "$1" =~ ^(--help|-h)$ ]]; then
        show_help
        exit 0
    fi
    run "$@"
    cleanup
}

if [ ! -n "$*" ]; then
    set /bin/sh "$@"
fi

main "$@"
