#!/bin/bash

WD=$(readlink -f ./test)
#WD=/mnt/memory
PG92_BIN=~/inst/pg9.2/bin
PG94_BIN=~/inst/pg9.4/bin

export LC_ALL=C
export PGDATABASE=test

[[ "$WD" ]] || exit 1
[[ -w "$WD" && -x "$WD" ]] || exit 1
cd "$WD" || exit 1

try_run ()
{
    exec 3>&1 4>&2
    exec > logfile 2>&1

    echo "init" >&4

    mkdir m s w

    "$PG92_BIN"/initdb -A trust -E UTF-8 --locale=C m/9.2 || exit 1
    "$PG94_BIN"/initdb -A trust -E UTF-8 --locale=C m/9.4 || exit 1

    cat <<EOF > m/9.2/postgresql.conf
port = 5430
shared_buffers = 32MB
wal_level = hot_standby
archive_mode = on
archive_command = 'test ! -f "$WD/w/%f" && cp %p "$WD/w/%f"'
max_wal_senders = 5
hot_standby = on
log_line_prefix = '%t '
log_checkpoints = on
lc_messages = C
autovacuum = off
log_min_messages = debug2
EOF
    cat <<EOF >> m/9.2/pg_hba.conf
local   replication     all                                trust
host    replication     all        127.0.0.1/32            trust
host    replication     all        ::1/128                 trust
EOF

    cp m/9.2/postgresql.conf m/9.4/postgresql.conf
    cp m/9.2/pg_hba.conf m/9.4/pg_hba.conf

    echo "start master 9.2" >&4

    "$PG92_BIN"/pg_ctl -w -D m/9.2 -l logfile.m.92 start || exit 1

    echo "base backup" >&4

    "$PG92_BIN"/pg_basebackup -p 5430 -c fast -X stream -D s/9.2/ || exit 1
    cat <<EOF >> s/9.2/postgresql.conf
port = 5431
EOF
    cat <<EOF > recovery.conf
restore_command = 'cp "$WD/w/%f" %p'
standby_mode = on
EOF
    cp s/9.2/postgresql.conf sb_postgresql.conf
    cp recovery.conf s/9.2/recovery.conf

    echo "start standby 9.2" >&4

    "$PG92_BIN"/pg_ctl -w -D s/9.2 -l logfile.s.92 start || exit 1

    #
    "$PG92_BIN"/psql -X -q -p 5430 -d postgres -c 'create database test' || exit 1
    "$PG92_BIN"/psql -X -q -p 5430 -f- <<EOF || exit 1
create unlogged table test (id int primary key, v text);
create index on test using hash (id);
insert into test select n, 'this is long line for fill table, line number ' || n from generate_series(1, 1000000) n;
EOF

    lsn=$("$PG92_BIN"/psql -X -At -q -p 5430 -c 'select pg_current_xlog_insert_location()') || exit 1

    echo "stop master 9.2" >&4

    "$PG92_BIN"/pg_ctl -w -D m/9.2 stop || exit 1

    echo "wait for standby catch up master: $lsn" >&4
    diff=-1
    while [[ "$diff" -lt 0 ]]; do
        sleep 1;
        diff=$("$PG92_BIN"/psql -X -At -q -p 5431 -c "select pg_xlog_location_diff(pg_last_xlog_replay_location(), '$lsn')")
        echo "diff: $diff" >&4
    done

    echo "promote standby 9.2" >&4
    "$PG92_BIN"/pg_ctl -w -D s/9.2 promote || exit 1

    echo "wait for promotion" >&4
    promoted=''
    while [[ ! $promoted ]]; do
        sleep 1;
        promoted=$("$PG92_BIN"/psql -X -At -q -p 5431 -c "select nullif(pg_is_in_recovery(), true)")
        echo "promoted: $promoted" >&4
    done

    echo "stop promoted new master 9.2" >&4

    "$PG92_BIN"/pg_ctl -w -D s/9.2 stop || exit 1

    "$PG92_BIN"/pg_controldata s/9.2/

    # upgrade

    echo "run upgrade" >&4

    "$PG94_BIN"/pg_upgrade -b "$PG92_BIN" -B "$PG94_BIN" -d s/9.2 -D m/9.4 -k -c || exit 1

    "$PG94_BIN"/pg_upgrade -b "$PG92_BIN" -B "$PG94_BIN" -d s/9.2 -D m/9.4 -k || exit 1

    echo "reset wal_level" >&4
    "$PG94_BIN"/pg_ctl -w -D m/9.4 -l logfile.m.94 start || exit 1
    "$PG94_BIN"/pg_ctl -w -D m/9.4 stop || exit 1

    ps axu | grep postgres

    exec 1>&3 2>&4
}

rm -r m s w logfile.* controldata.* analyze_new_cluster.sh delete_old_cluster.sh recovery.conf rsync.log logfile sb_postgresql.conf

try_run || exit 1
