#!/bin/bash
set -eo pipefail

trap cleanup EXIT

# Defaults
REGISTRY=registry.redhat.io
IMAGE=rhel8/support-tools
AUTHFILE=/var/lib/kubelet/config.json
TOOLBOX_NAME=toolbox-"$(whoami)"
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
        if container_exists; then
            sudo podman rm "${TOOLBOX_NAME}"
        fi
    elif ! image_fresh; then
        read -r -p "There is a newer version of ${TOOLBOX_IMAGE} available. Would you like to pull it? [y/N] "

        if [[ ${REPLY} =~ ^([Yy][Ee][Ss]|[Yy])+$ ]]; then
            image_pull
            if container_exists; then
                sudo podman rm "${TOOLBOX_NAME}"
            fi
        else
            echo "Skipping retrieval of new image.."
        fi
    fi

    local runlabel=$(image_runlabel)
    if ! container_exists; then
        echo "Spawning a container '${TOOLBOX_NAME}' with image '${TOOLBOX_IMAGE}'"
        if [[ -z "${runlabel}" ]] || [[ "${runlabel}" == "<no value>" ]]; then
            container_create
        else
            echo "Detected RUN label in the container image. Using that as the default..."
            container_create_runlabel
        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}" == created ]] || [[ "${state}" == exited ]] || [[ "${state}" == stopped ]]; then
        container_start
    elif [[ "${state}" != running ]]; then
        echo "Container '${TOOLBOX_NAME}' in unknown state: '$state'"
        return 1
    fi

    if [[ "$#" -eq "0" ]]; then
        echo "Container started successfully. To exit, type 'exit'."
    fi
    container_exec "$@"
}

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

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

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

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

# returns 0 if the image on disk is "fresh", i.e. no newer image on remote
# registry. (or if we couldn't inspect the registry successfully)
image_fresh() {
    echo "Checking if there is a newer version of ${TOOLBOX_IMAGE} available..."
    local_date=$(sudo podman image inspect "${TOOLBOX_IMAGE}" --format '{{.Created}}')

    if ! remote_date=$(sudo skopeo inspect --authfile "${AUTHFILE}" docker://"${TOOLBOX_IMAGE}" --format '{{.Created}}'); then
        echo "Error inspecting ${TOOLBOX_IMAGE} via skopeo"
        return
    fi
    # if the date on the registry is *NOT* newer than the local image date
    # then we return 1. (doing a less-than comparison of the strings always
    # fails if they are the same, hence the weird conditional here)
    ! [[ "${remote_date}" > "${local_date}" ]]
}

image_runlabel() {
    sudo podman image inspect "${TOOLBOX_IMAGE}" --format '{{- if index .Labels "run" -}}{{.Labels.run}}{{- end -}}'
}


image_pull() {
    if ! sudo --preserve-env podman pull --authfile "${AUTHFILE}" "${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 --authfile "${AUTHFILE}" "${REGISTRY}"
            sudo --preserve-env podman pull --authfile "${AUTHFILE}" "${TOOLBOX_IMAGE}"
        else
            echo "Exiting..."
            exit 1
        fi
    fi
}

container_create() {
    if ! sudo podman create \
        --hostname toolbox \
        --name "${TOOLBOX_NAME}" \
        --privileged \
        --net=host \
        --pid=host \
        --ipc=host \
        --tty \
        --interactive \
        -e HOST=/host \
        -e NAME="${TOOLBOX_NAME}" \
        -e IMAGE="${IMAGE}" \
        --security-opt label=disable \
        --volume /run:/run \
        --volume /var/log:/var/log \
        --volume /etc/machine-id:/etc/machine-id \
        --volume /etc/localtime:/etc/localtime \
        --volume /:/host \
        "${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_create_runlabel() {
    # Variable replacement logic reproduced from:
    # https://github.com/containers/podman/blob/29d7ab3f82e38c442e449739e218349b9a4a16ea/pkg/domain/infra/abi/containers_runlabel.go#L226
    local pod
    pod="$(echo "${runlabel}" \
        | sed 's/podman run/sudo podman create/' \
        | sed 's/--name NAME/--name ${TOOLBOX_NAME}/' \
        | sed 's/NAME=NAME/NAME=${TOOLBOX_NAME}/' \
        | sed 's/IMAGE=IMAGE/IMAGE=${TOOLBOX_IMAGE}/' \
        | sed 's/host IMAGE/host ${TOOLBOX_IMAGE}/')"
    if ! eval "${pod}" ; then
        echo "$0: failed to create container from runlabel '${TOOLBOX_NAME}'"
        exit 1
    fi
}

container_exec() {
    if [[ "$#" -eq 0 ]]; then
        cmd=$(sudo podman image inspect "${TOOLBOX_IMAGE}" | jq -re ".[].Config.Cmd[0]") || cmd="/bin/sh"
        sudo podman exec \
            --env LANG="${LANG}" \
            --env TERM="${TERM}" \
            --tty \
            --interactive \
            "${TOOLBOX_NAME}" \
            "${cmd}"
    else
        sudo podman exec \
            --env LANG="${LANG}" \
            --env TERM="${TERM}" \
            --tty \
            --interactive \
            "${TOOLBOX_NAME}" \
            "$@"
    fi
}

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}
- AUTHFILE: The location where your registry credentials are stored. Default: ${AUTHFILE}

Example toolboxrc:
REGISTRY=my.special.registry.example.com
IMAGE=debug:latest
TOOLBOX_NAME=special-debug-container
AUTHFILE=/home/core/.docker/config.json"
}

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
}

main "$@"
