#!/bin/bash

set -e

DB_HOST="localhost"
DB_PORT=5443
PGPASSWORD="xivocc"
DB_USERNAME="postgres"

DB_MIGRATION_VERSION="2023.04"
FACTORY_ENV_FILE="/etc/docker/compose/factory.env"
PG_DATA_FOLDER="/var/lib/postgresql"
PG_15_DATA="$PG_DATA_FOLDER/15"


locale_fr="fr_FR.utf8"
db_data_folder_old="$PG_DATA_FOLDER/11/main"

is_postgres_running() {
    result=$(PGPASSWORD=xivocc psql -h "$DB_HOST" -p $DB_PORT -U postgres -qAtc "select 1 from pg_catalog.pg_database WHERE datname='postgres'" 2>/dev/null)

    [ $? -eq 0 ] && [ "$result" = "1" ]
}

properly_shutdown_database() {
    xivocc-dcomp stop pgxivocc
}

get_distribution() {
    local distribution=$(grep -oP -m 1 '^\s*XIVOCC_DIST=\K.*' ${FACTORY_ENV_FILE})
    echo -e "$distribution"
}

migrate_11_to_15() {
    set -o pipefail
    local distribution=$(get_distribution)
    # Note: Using implicit parameter from Dockerfile: PGDATANEW /var/lib/postgresql/11/main
    docker run --rm \
        -v /etc/timezone:/etc/timezone:ro \
        -v /etc/localtime:/etc/localtime:ro \
        -v /var/lib/postgresql/:/var/lib/postgresql/ \
        -e LANG="${locale_fr}" \
        -e POSTGRES_INITDB_ARGS="${postgres_initdb_args}" \
        -e PGDATAOLD="$db_data_folder_old" \
        xivoxc/xivo-db-migration:${DB_MIGRATION_VERSION}."${distribution}" --link 2>&1
}

display_upgrade_notice() {
    echo -e "\e[32m*********************************************************************************"
    echo -e "*   XiVO-CC Database was upgraded from Postgres version 11 to version 15        *"
    echo -e "*********************************************************************************\e[0m"
}

clean_pg_upgrade_remainders() {
    echo -e  "\e[33mRemove old cluster and clean pg_upgrade files\e[0m"
    rm -rf "${PG_DATA_FOLDER}/11" \
           "${PG_DATA_FOLDER}/data" \
        /var/lib/postgresql/delete_old_cluster.sh
}

add_access_configuration() {
    cp "${db_data_folder_old}/pg_hba.conf" "${PG_DATA_FOLDER}/15/data"
}

wait_for_postgres() {
    local wait_time=120
    echo -e -n "Waiting $wait_time seconds for database db..."

    local db_running="false"
    for _ in $(seq 1 $wait_time); do
        if is_postgres_running; then
            db_running="true"
            break
        else
            sleep 1
            echo -e -n "."
        fi
    done
    echo
    if [ "$db_running" = "false" ]; then
        echo -e "\e[31mERROR: database is not running.\e[0m"
        exit 1
    fi
}


pull_and_start_db() {
    xivocc-dcomp upgrade-db
}


run_psql_file() {
  PGPASSWORD=${PGPASSWORD} psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -t -f "$1"
}

migrate() {
    local distribution=$(get_distribution)
    echo -e "\e[32mStarting database migration to postgres 15...\e[0m"

    echo -e "\e[33mRe-starting database with fast shutdown...\e[0m"

    properly_shutdown_database
    if is_postgres_running; then
        echo -e "\e[31mERROR: Failed to stop database.\e[0m"
        exit 3
    fi

    echo -e "\e[33mPulling docker migration container...\e[0m"

    docker pull xivoxc/xivo-db-migration:${DB_MIGRATION_VERSION}."${distribution}"


    echo -e "\e[33mRunning migration...\e[0m"
    migrate_11_to_15



    if [ "$?" -eq 0 ]; then
        echo -e "\e[32mDatabase upgrade successful.\e[0m"
        set +o pipefail

        echo -e "\e[33mRetrieving old pg_hba.conf...\e[30m"
        add_access_configuration

        echo -e "\e[33mStarting database container...\e[0m"
        pull_and_start_db
        wait_for_postgres
        if [ -f "/var/lib/postgresql/update_extensions.sql" ]; then
          run_psql_file "/var/lib/postgresql/update_extensions.sql"
        fi
        clean_pg_upgrade_remainders

        display_upgrade_notice
    fi
}

if [ ! -d "$PG_15_DATA" ]; then
    migrate
else
    echo -e "\e[31mERROR: $PG_15_DATA directory exists.\e[0m"
fi

exit 0
