#!/usr/bin/env bash
set -e

script=$(basename "$0")
version="1.0.1"

help() {
    echo
    echo "$script"
    echo
    echo 'Description: Upgrade Postgres Docker container.'
    echo "Syntax: $script [-c|-s|-t|-i|-V|help]"
    echo 'Example: $script -c postgres01 -s postgres:12-alpine -t postgres:14-alpine -i /var/tmp/postgres01/20241028094730.sql'
    echo 'options:'
    echo '  -c    Docker container.'
    echo '  -s    Source image version.'
    echo '  -t    Target image version.'
    echo '  -i    Skip export and run import for dump only.'
    echo "  -V    Show $script version."
    echo "  help  Show $script manual."
    echo
}

if [[ "$1" == 'help' ]]; then
    help
    exit
fi

source_version=

while getopts ':c: :s: :t: :i: :V' opt; do
    case $opt in
        c) container="$OPTARG";;
        s) source_version="$OPTARG";;
        t) target_version="$OPTARG";;
        i) dump_file="$OPTARG";;
        r) replace='true';;
        V) echo "$script version $version"
        exit 0
        ;;
        \?) echo "Invalid option -$OPTARG" >&2
        help
        exit;;
    esac
done

source_version=${source_version:-"$target_version"}

[[ -z "$container" ]] && { echo 'Parameter -c|container is empty.' ; exit 1; }
[[ -z "$target_version" ]] && { echo 'Parameter -t|target is empty.' ; exit 1; }

container_id=$(docker ps -f "name=${container}" -q | head -n1)
[[ -z "$container_id" ]] && { echo "Container id for $container not found." ; exit 1; }

current_version=$(docker inspect --format='{{.Config.Image}}' $container_id)
if [[ "$current_version" != "$source_version" ]]; then
    echo "$container image is not $source_version."
    exit 1
fi

echo "Pulling $target_version ..."
docker pull "$target_version"

if [[ -z "$dump_file" ]]; then

    timestamp=$(date +%Y%m%d%H%M%S)
    dump_file="/var/tmp/$container/$timestamp.sql"

    mkdir -p "/var/tmp/$container"
    docker exec $container_id /bin/bash -c "pg_dumpall -U \$POSTGRES_USER $database" > "$dump_file"
    echo "Dumped all databases from $container to $dump_file"

    volume_names=$(docker inspect --format '{{ range .Mounts }}{{ .Name }} {{ end }} ' $container_id)
    echo "Stopping and removing container $container and volumes ${volume_names} ..."
    read -p 'Woul you like to proceed with the deletion? [y/n] '
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        docker stop $container_id
        docker rm $container_id
        docker volume rm $volume_names
    else
        echo 'Exiting script. Please restart the script.'
        exit
    fi

    echo "Please deploy the new container with name $container and image $target_version."
    read -p 'Is the new container deployed and running? [y/n] '
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        echo 'Continuing with database import.'
    else
        echo 'Exiting script. Please restart the script:'
        echo "docker-postgres-upgrade -c $container -s $source_version -t $target_version -i $dump_file"
        exit
    fi
fi

echo "Importing all databases from $dump_file to $container"
cat $dump_file | docker exec -i "$container" /bin/bash -c "psql -U \$POSTGRES_USER"

postgres_user=$(docker exec $container /bin/bash -c "echo \$POSTGRES_USER")
echo "Reset $postgres_user password for $container ..."
postgres_password=$(docker exec $container /bin/bash -c "echo \$POSTGRES_PASSWORD")
docker exec $container /bin/bash -c "psql -U \$POSTGRES_USER -c \"ALTER USER $postgres_user WITH PASSWORD '$postgres_password';\""
