#! /bin/bash

set -e

. test/pg-test-lib.sh

ADMIN_PASSWORD=redhat

STEPS=( "$@" )

quote_args ()
{
    quote_args_result=
    local space=
    for arg; do
        quote_args_result+="$space$(printf "%q" "$arg")"
        space=' '
    done
}

quote_args_print ()
{
    quote_args "$@"
    echo "$quote_args_result"
}

# background_container IMAGE DOCKER_ARGS CMD
background_container ()
{
    CID=$(eval "docker run -d $2 $1 $3")
    test -n "$CID"
}

# run_server DATADIR IMAGE_ID DOCKER_ARGS
run_server ()
{
    local datadir=$1
    local image_id=$2
    local docker_args=$(quote_args_print -e POSTGRESQL_ADMIN_PASSWORD="$ADMIN_PASSWORD")
    docker_args+=' '$(quote_args_print -v "$datadir:/var/lib/pgsql/data:Z")
    docker_args+=" $3"
    background_container "$image_id" "$docker_args"
}

# init_datadir IMAGE_ID dataspec
# ------------------------------
init_datadir ()
{
    local image_id=$1
    DATADIR=$(mktemp -d)
    setfacl -m u:26:rwx "$DATADIR"
    run_server "$DATADIR" "$image_id"
    wait_for_postgres "$CID"

    eval "data_$2_create"
    eval "data_$2_check"

    docker stop "$CID" >/dev/null
    docker rm -f "$CID" >/dev/null
}


# check_upgrade_path {hardlink|copy} dataspec
assert_upgrade_succeeds ()
{
    info "Initializing datadir with $VERSION_FROM PostgreSQL"
    local INIT_IMAGE=$(get_image_id "$VERSION_FROM")
    local dataspec=$2
    init_datadir "$INIT_IMAGE" "$dataspec"

    info "Running upgrade '$1/$dataspec'"

    for upgrade_to in "${UPGRADE_PATH[@]}"; do
        info "Upgrading to $upgrade_to"
        UPGRADE_IMAGE=$(get_image_id "$upgrade_to")
        run_server "$DATADIR" "$UPGRADE_IMAGE" "-e POSTGRESQL_UPGRADE=$1"
        wait_for_postgres "$CID"
        eval "data_${dataspec}_check"
        debug "the upgrading container of version '$upgrade_to' responded"
        docker stop "$CID" >/dev/null
        docker rm -f "$CID" >/dev/null

        run_server "$DATADIR" "$UPGRADE_IMAGE"
        wait_for_postgres "$CID"
        eval "data_${dataspec}_check"
        debug "restarted server of version '$upgrade_to' responded"
        docker stop "$CID" >/dev/null
        docker rm -f "$CID" >/dev/null
    done
}

VERSION_FROM=$1 ; shift
UPGRADE_PATH=( "$@" )
for data in empty pagila; do
    assert_upgrade_succeeds hardlink "$data"
    assert_upgrade_succeeds copy "$data"
done
