#!/usr/bin/perl

use strict;
use warnings;

use IPC::Run;
use PostgreSQL::Test::Cluster;
use PostgreSQL::Test::Utils;

sub pgbench_async
{
	my ($node, @args) = @_;

	my ($in, $out, $err, $rc);
	$in = '';
	$out = '';

	my @cmd = (
		'pgbench',
		-h => $node->host(),
		-p => $node->port(),
		$node->{dbname} || 'postgres',
		@args
	);
	print("running pgbench: " . join(" ", @cmd), "\n");
	my $handle = IPC::Run::start(\@cmd, $in, $out);
	return $handle;
}

sub pgbench_await
{
	my ($pgbench_handle) = @_;
	IPC::Run::finish($pgbench_handle);
	my $exit_code = ($? >> 8);
	print("finished pgbench\n");
}

sub pgbench {
	my ($node, @args) = @_;
	my $h = pgbench_async($node, @args);
	pgbench_await($h);
}

sub psql_async
{
	my ($node, @args) = @_;

	my ($in, $out, $err, $rc);
	$in = '';
	$out = '';

	my @cmd = (
		'psql',
		-h => $node->host(),
		-p => $node->port(),
		$node->{dbname} || 'postgres',
		@args
	);
	print("running psql: " . join(" ", @cmd));
	my $handle = IPC::Run::start(\@cmd, $in, $out);
	return $handle;
}

sub psql_await
{
	my ($h) = @_;
	IPC::Run::finish($h);
	print("finished psql\n");
}

sub psql {
	my ($node, @args) = @_;
	my $h = psql_async($node, @args);
	pgbench_await($h);
}

my $node = PostgreSQL::Test::Cluster->new("master");
$node->init();
$node->append_conf('postgresql.conf', 'wal_level = replica');
$node->start();
$node->safe_psql("postgres", "create extension pg_walinspect;");

my $out;

# Create physical replication slot
$out = $node->safe_psql("postgres", "select pg_create_physical_replication_slot('myslot', true, false)");
print($out);

$out = $node->safe_psql("postgres", "select restart_lsn from pg_replication_slots where slot_name = 'myslot'");
print("replication slot is created with restart_lsn: " . $out, "\n");

# Create new WAL segments
pgbench($node, (-i, -s => 10));

# Start checkpoint execution
my $h1 = psql_async($node, (-c => 'checkpoint'));

# Advance replication slot during checkpoint
sleep(1);
$out = $node->safe_psql("postgres", "select pg_replication_slot_advance('myslot', pg_current_wal_lsn())");
print("advancing slot: \n");
print($out, "\n");

# Wait for checkpoint completion
psql_await($h1);

$node->stop("immediate");
$node->start();

$out = $node->safe_psql("postgres", "select pg_get_wal_record_info(restart_lsn) from pg_replication_slots where slot_name = 'myslot'");
print($out . "\n");
