#!/usr/bin/env bash

here="$(cd -P "$(dirname "${BASH_SOURCE:-0}")" && pwd -P)"
export PGENV_CLUSTER_ROOT="$here/rewind-study"
export PGDATABASE=postgres

# Step no
no=1

go_step() {
  [ $no -gt 1 ] && echo ""
  echo "# [Step-$no] $(date)"
  printf "# %s, go?\n[ENTER(yes)|n(no)|s(stop)]: " "$1"
  read line
  echo

  ((no+=1))

  # stop
  if [ "$line" = "s" ]; then
    exit 0
  fi

  # skip
  if [ "$line" = "n" ]; then
    return 1
  fi

  :
}

[ -d "$PGENV_CLUSTER_ROOT" ] && {
  pgenv cluster stop -a
  rm -rf "$PGENV_CLUSTER_ROOT"
  echo ""
}

### Start study steps ###

go_step "Setup a cluster" && {
  pgenv cluster setup -s standby primary
}


go_step "Rewrite postgresql.conf" && {
  pgenv cluster stop -a

  {
    cat<<EOF
shared_buffers = 1024MB
wal_log_hints = on
wal_keep_segments = 5
max_wal_size = 300MB
archive_timeout = 10min
log_checkpoints = on
log_error_verbosity = verbose
autovacuum = off
log_min_messages = info
bgwriter_delay = 5000ms
EOF
  } >> "$PGENV_CLUSTER_ROOT"/primary.conf

  {
    cat <<EOF
wal_log_hints = on
shared_buffers = 1024MB
max_wal_size = 300MB
wal_keep_segments = 5
archive_timeout = 10min
log_checkpoints = on
log_error_verbosity = verbose
autovacuum = off
log_min_messages = info
bgwriter_delay = 5000ms
EOF
  } >> "$PGENV_CLUSTER_ROOT"/standby.conf
}


go_step "Start cluster" && {
  pgenv cluster start -a
  pgenv cluster status
}


go_step "Insert some data to primary" && {
  psql -a -p 24312 -d postgres <<EOF
create table if not exists t (c text) WITH (FILLFACTOR=70);;
insert into t select 'a'||i from generate_series(1,1000) as i;
checkpoint;
EOF

  psql -a -p 24312 <<EOF
select pg_current_wal_lsn();
EOF
}


go_step "Down primary" && {
  pg_ctl stop -D "$PGENV_CLUSTER_ROOT"/primary -m i
  sleep 2
}


go_step "Promote standby" && {
  pg_ctl promote -D "$PGENV_CLUSTER_ROOT"/standby
  sleep 2
}


go_step "Start primary(old)" && {
  sed -e /synch/d "$PGENV_CLUSTER_ROOT"/primary.conf > "$PGENV_CLUSTER_ROOT"/primary.conf.bak
  cp "$PGENV_CLUSTER_ROOT"/primary.conf.bak "$PGENV_CLUSTER_ROOT"/primary.conf

  pg_ctl start -D "$PGENV_CLUSTER_ROOT"/primary
}


go_step "Insert and update some data into primary(old)" && {
  psql -a -p 24312 -d postgres <<EOF
insert into t select 'primary'||i from generate_series(1,100000) as i;
update t set c = 'updated' where ctid = '(0,1)';
EOF
}


go_step "Stop primary(old)" && {
  pg_ctl stop -D "$PGENV_CLUSTER_ROOT"/primary
}


go_step "Insert some data into standby(new primary)" && {
  psql -a -p 24313 -d postgres <<EOF
insert into t select 'standby'||i from generate_series(1,1000) as i;
EOF

  cp "$PGENV_CLUSTER_ROOT"/primary/postgresql.conf "$PGENV_CLUSTER_ROOT"/postgresql.conf
}


go_step "Rewind primary(old)" && {
  pg_rewind --debug -D "$PGENV_CLUSTER_ROOT"/primary -P --source-server="host=localhost dbname=postgres port=24313"

  cp "$PGENV_CLUSTER_ROOT"/postgresql.conf "$PGENV_CLUSTER_ROOT"/primary/postgresql.conf
  cat <<EOF > "$PGENV_CLUSTER_ROOT"/primary/recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=''$USER''  host=localhost port=24313 application_name=primary sslmode=disable sslcompression=1'
recovery_target_timeline = 'latest'
#restore_command = 'cp "$PGENV_CLUSTER_ROOT/archivedir/%f" "%p"'
EOF
}


go_step "Start primary(old)" && {
  pg_ctl start -D "$PGENV_CLUSTER_ROOT"/primary

  echo "wal position of new standby"
  psql -a -p 24313 <<EOF
select pg_current_wal_lsn();
EOF

  echo "wal position of new primary"
  psql -a -p 24312 <<EOF
select pg_last_wal_replay_lsn();
EOF

  pgenv cluster status
}
