#!/opt/local/bin/perl

use strict;
use warnings;
use File::Path qw(remove_tree);
use IPC::Run;
use Time::HiRes qw(gettimeofday tv_interval);

my $backup_dir = 'pgbackup';
my @result_order;
my %results;

my @base_cmd = ('pg_basebackup', '-D', $backup_dir);

my @manifest_options = (
	{ 'name' => 'omit', 'options' => ['--no-manifest' ] },
	{ 'name' => 'none', 'options' => ['--manifest-checksums=none' ] },
	{ 'name' => 'crc32c', 'options' => ['--manifest-checksums=crc32c' ] },
	{ 'name' => 'sha256', 'options' => ['--manifest-checksums=sha256' ] },
);

my @connection_options = (
	{ 'name' => 'unix', 'options' => [] },
	{ 'name' => 'tcp',
	  'options' => [ '-d', 'host=127.0.0.1 sslmode=disable' ] },
	{ 'name' => 'tcpssl',
	  'options' => [ '-d', 'host=127.0.0.1 sslmode=require' ] },
);

my @output_options = (
	{ 'name' => 'plain', 'options' => [ '-Fp' ] },
	{ 'name' => 'tar', 'options' => [ '-Ft' ] },
	{ 'name' => 'targzip', 'options' => [ '-Ft', '-z' ] },
);

remove_tree($backup_dir);

for my $n (1, 2, 3)
{
	for my $mopt (@manifest_options)
	{
		for my $copt (@connection_options)
		{
			for my $oopt (@output_options)
			{
				my @cmd = @base_cmd;
				push @cmd, @{$mopt->{'options'}};
				push @cmd, @{$copt->{'options'}};
				push @cmd, @{$oopt->{'options'}};

				my @tag;
				push @tag, $copt->{'name'};
				push @tag, $oopt->{'name'};
				push @tag, 'm:' . $mopt->{'name'};
				my $tag = join '+', @tag;

				doit($tag, @cmd);
			}
		}
	}
}

print "\n=== result summary ===\n";
for my $tag (@result_order)
{
	print $tag, ' ', join(' ', @{$results{$tag}}), "\n";
}

sub doit
{
	my ($tag, @cmd) = @_;

	my $t0 = [ gettimeofday() ];
	IPC::Run::run(@cmd);
	my $elapsed = tv_interval( $t0, [ gettimeofday() ]);
	print $tag, " ", $elapsed, "\n";
	push @result_order, $tag if !exists $results{$tag};
	push @{$results{$tag}}, $elapsed;

	remove_tree($backup_dir);
}
