#!/bin/bash
#
# First argument : number of tables
# Second argument : size[Byte] of each tables
# Third argument : max_sync_workers
# Fourth argument : execution numbers
# Fifth argument: test prefix
#

port_pub=5431
data_pub=datapub

port_sub=5432
data_sub=datasub

echo '########################'
echo '# Check configurations #'
echo '########################'

declare num_tables
if [ -n "$1" ]; then
    num_tables=$1
else
    num_tables=10
fi

echo "$num_tables tables will be used while testing"

declare table_size
if [ -n "$2" ]; then
    table_size=$2
else
    table_size=0
fi

num_sync_workers=$3
run_no=$4
prefix=$5

# logname must be defined here

log_pub=pub_${prefix}_${num_tables}_${table_size}_${num_sync_workers}_${run_no}.log
log_sub=sub_${prefix}_${num_tables}_${table_size}_${num_sync_workers}_${run_no}.log

#
# Convert from table_size to number of tuples. The equation was
# found by my tests...
#

declare num_tuples
if [ $table_size == "10kB" ]
then
    num_tuples=3250
else
    num_tuples=0
fi

echo "$num_tuples tuples will be inserted to each tables"


echo '############'
echo '# Clean up #'
echo '############'

pg_ctl stop -D $data_pub -w
pg_ctl stop -D $data_sub -w

rm -rf $data_pub $data_sub

echo '##########'
echo '# Set up #'
echo '##########'

initdb -D $data_pub -U postgres
initdb -D $data_sub -U postgres

cat << EOF >> $data_pub/postgresql.conf
wal_level = logical
wal_sender_timeout = 0
wal_receiver_timeout = 0
port = $port_pub
shared_buffers = 40GB
max_worker_processes = 32
max_parallel_maintenance_workers = 24
max_parallel_workers = 32
synchronous_commit = off
checkpoint_timeout = 1d
max_wal_size = 24GB
min_wal_size = 15GB
autovacuum = off
max_sync_workers_per_subscription = 8
log_line_prefix = '%n [%p] '
max_wal_senders = 200
max_replication_slots = 200
EOF

cat << EOF >> $data_sub/postgresql.conf
wal_level = logical
wal_sender_timeout = 0
wal_receiver_timeout = 0
port = $port_sub
shared_buffers = 40GB
max_worker_processes = 32
max_parallel_maintenance_workers = 24
max_parallel_workers = 32
synchronous_commit = off
checkpoint_timeout = 1d
max_wal_size = 24GB
min_wal_size = 15GB
autovacuum = off
max_sync_workers_per_subscription = $num_sync_workers
max_logical_replication_workers = 50
log_line_prefix = '%n [%p] '
max_replication_slots = 200
EOF

pg_ctl -D $data_pub start -w -l $log_pub
pg_ctl -D $data_sub start -w -l $log_sub

#
# Setup the IPC tables and Procedures
#
(
    echo "CREATE TABLE ipc(msg text);"
    echo "ALTER TABLE ipc ADD COLUMN ts TIMESTAMP;"
    echo "ALTER TABLE ipc ALTER COLUMN ts SET DEFAULT now();"
    echo "CREATE OR REPLACE PROCEDURE ipc_wait_for(state TEXT) AS \$\$
    DECLARE
    BEGIN
        RAISE NOTICE 'wait for state %', state;
        WHILE NOT EXISTS (SELECT 1 FROM ipc WHERE msg = state) LOOP
            RAISE NOTICE 'waiting until state %', state;
            EXECUTE 'SELECT pg_sleep(0.1);';
         END LOOP;
         RAISE NOTICE 'ok, reached state %', state;
    END;
    \$\$ LANGUAGE plpgsql;
"
) | psql -U postgres -p $port_pub -a

(
    echo "CREATE TABLE ipc(msg text);"
    echo "ALTER TABLE ipc ADD COLUMN ts TIMESTAMP;"
    echo "ALTER TABLE ipc ALTER COLUMN ts SET DEFAULT now();"
    echo "CREATE OR REPLACE PROCEDURE ipc_wait_for(state TEXT) AS \$\$
    DECLARE
    BEGIN
        RAISE NOTICE 'wait for state %', state;
        WHILE NOT EXISTS (SELECT 1 FROM ipc WHERE msg = state) LOOP
            RAISE NOTICE 'waiting until state %', state;
             EXECUTE 'SELECT pg_sleep(0.1);';
        END LOOP;
        RAISE NOTICE 'ok, reached state %', state;
    END;
    \$\$ LANGUAGE plpgsql;
"
) | psql -U postgres -p $port_sub -a

