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

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

#
# 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 '# IPC at subscriber-side #'
echo '##########################'

psql -U postgres -p $port_sub -a -c "CREATE SUBSCRIPTION ipc_from_publisher CONNECTION 'host=localhost user=postgres port=$port_pub' PUBLICATION ipc_at_publisher WITH(origin=NONE);"
psql -U postgres -p $port_sub -a -c "CREATE PUBLICATION ipc_at_subscriber FOR TABLE ipc;"

# wait a bit for the publisher-side to connect to this publication
sleep 5s

psql -U postgres -p $port_sub -a -c "INSERT INTO ipc VALUES('sub ipc ready');"
psql -U postgres -p $port_sub -a -c "CALL ipc_wait_for('pub ipc ready');"

echo '#################'
echo '# Create tables #'
echo '#################'
(
    echo "CREATE TABLE busy_tbl(a text);"

    echo "CREATE SCHEMA test_tables;"
    echo -e "SELECT 'CREATE TABLE test_tables.manytables_'||i||'(i int);' FROM generate_series(1, $num_tables) g(i) \gexec"

) | psql -U postgres -p $port_sub -a

sleep 1s

echo '######################################'
echo '# Create subscription for busy table #'
echo '######################################'
(
    echo "CREATE SUBSCRIPTION mysub CONNECTION 'host=localhost user=postgres port=$port_pub' PUBLICATION mypub;"
    echo "INSERT INTO ipc VALUES ('mysub is created');"

) | psql -U postgres -p $port_sub -a


echo '########'
echo '# Test #'
echo '########'
(
    echo -e "CREATE OR REPLACE PROCEDURE log_rep_test(max INTEGER) AS \$\$
    DECLARE
        total_duration INTERVAL := '0';
        avg_duration FLOAT := 0.0;
        start_time TIMESTAMP;
        end_time TIMESTAMP;
    BEGIN
        start_time := clock_timestamp();

        -- time how long it takes for all the tablesyncs to become "ready"
        WHILE EXISTS (SELECT 1 FROM pg_subscription_rel WHERE srsubstate != 'r') LOOP
            COMMIT;
        END LOOP;

        end_time := clock_timestamp();

        total_duration := total_duration + (end_time - start_time);
    
        IF max > 0 THEN
            avg_duration := EXTRACT(EPOCH FROM total_duration) / max * 1000;
        END IF;
    
        RAISE NOTICE 'RESULT: %', avg_duration;
    END;
    \$\$ LANGUAGE plpgsql;
"
) | psql -U postgres -p $port_sub -a


psql -U postgres -p $port_sub -a -c "CALL ipc_wait_for('pub busy started');"

# This alter/refresh will cause all the test tables to participate in the subscription
psql -U postgres -p $port_sub -a -c "INSERT INTO ipc VALUES ('test started');"
psql -U postgres -p $port_sub -a -c "ALTER SUBSCRIPTION mysub REFRESH PUBLICATION;"
psql -U postgres -p $port_sub -a -c "CALL log_rep_test(1);"
psql -U postgres -p $port_sub -a -c "INSERT INTO ipc VALUES ('test finished');"

psql -U postgres -p $port_sub -a -c "CALL ipc_wait_for('pub busy finished');"
psql -U postgres -p $port_sub -a -c "SELECT count(*) FROM busy_tbl;"

psql -U postgres -p $port_sub -a -c "DROP SUBSCRIPTION mysub;"
psql -U postgres -p $port_sub -a -c "DROP SUBSCRIPTION ipc_from_publisher;"
psql -U postgres -p $port_sub -a -c "DROP PUBLICATION ipc_at_subscriber;"
