#!/bin/bash

# Start and stop various versions of ClickHouse containers. Requires that an
# OCI runner like Docker or Orb be running and the `docker` CLI.

set -e

usage() {
    cat <<EOF
Usage: choci <command> [<args>]

The choci commands are:
    start [<version>]   Start ClickHouse version; defaults to latest
    stop                Stop the current ClickHouse server
    status              Show status of server
    download <version>  Download a version
    remove <version>    Remove a version
    versions            Show currently-downloaded versions
    help                Show this usage statement and command summary
EOF
}

# https://stackoverflow.com/a/246128
dir="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
image="clickhouse/clickhouse-server"
name="$(basename "${BASH_SOURCE[0]}")"

cfg_file() {
    # Determine which file from ./configs to use.
    local version="$1"
    # Default config.
    fn=default
    if [[ "$version" =~ [.][0-9]+$ ]] && [ "${version%%.*}" -lt 25 ]; then
        fn=allow_object
        # Enable the JSON type in release prior to 2025.
        if [ "${version:0:4}" == "24.8" ]; then
            # The setting was renamed.
            fn=allow_json
        fi
    fi

    echo "$fn"
}
stop() {
    cid="$(docker ps -aq --filter "name=$name")"
    if [ -n "$cid" ]; then
        printf 'Stopping ClickHouse instance %s...\n' "$cid"
        docker rm -f "$cid"
    fi
}

case "$1" in
    stop)
        stop
        ;;
    start)
        version="${2:-latest}"
        stop
        cfg_base="$(cfg_file "$version")"
        printf 'Starting ClickHouse %s\n' "$version"
        docker run -p 8123:8123 -p9000:9000 \
            -e CLICKHOUSE_SKIP_USER_SETUP=1 \
            --name "$name" \
            --ulimit nofile=262144:262144 \
             -v "$dir/configs/$cfg_base.yaml:/etc/clickhouse-server/users.d/$cfg_base.yaml" \
             -d "$image:$version"
        ;;
    download)
        version="${2:-latest}"
        docker pull "$image:$version"
        ;;
    status)
        docker ps -f "name=$name" --format "table {{.Names}}\t{{.Image}}\t{{.State}}"
        ;;
    remove)
        version="$2"
        if [ -z "$version" ]; then
            printf 'No version specified\n'
            usage
            exit 1;
        fi
        docker image rm -f "$image:$version"
        ;;
    versions)
        docker image ls --filter "reference=$image:*" --format '{{.Tag}}'
        ;;
    help)
        usage
        ;;
    *)
        test -n "$1" && printf 'Unknown command:  %s\n\n' "$1"
        usage
        exit 1;
        ;;
esac
