#include <libpq-fe.h>

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(int argc, char *argv[])
{
	PGconn *master;
	PGconn *standby;
	PGresult *result;
	int i;
	int loops = 10000;
	char buffer[1024];
	const char *level = "off";
	bool check_applied = false;

	for (i = 1; i != argc; ++i)
	{
		bool more = (i < argc - 1);

		if (strcmp(argv[i], "--check") == 0)
			check_applied = true;
		else if (strcmp(argv[i], "--level") == 0 && more)
			level = argv[++i];
		else if (strcmp(argv[i], "--loops") == 0 && more)
			loops = atoi(argv[++i]);
		else
		{
			fprintf(stderr, "bad argument\n");
			exit(1);
		}
	}

	master = PQconnectdb("dbname=postgres port=5432");
	assert(PQstatus(master) == CONNECTION_OK);

	standby = PQconnectdb("dbname=postgres port=5433");
	assert(PQstatus(standby) == CONNECTION_OK);

	snprintf(buffer, sizeof(buffer), "SET synchronous_commit = %s", level);
	result = PQexec(master, buffer);
	assert(PQresultStatus(result) == PGRES_COMMAND_OK);
	PQclear(result);

	result = PQexec(master, "CREATE TABLE counter AS SELECT 0 AS n");
	assert(PQresultStatus(result) == PGRES_COMMAND_OK ||
		 strcmp(PQresultErrorField(result, PG_DIAG_SQLSTATE), "42P07") == 0);
	PQclear(result);

	for (i = 0; i < loops; ++i)
	{
		/*printf("Updating master...\n");*/
		snprintf(buffer, sizeof(buffer), "UPDATE counter SET n = %d", i);
		result = PQexec(master, buffer);
		assert(PQresultStatus(result) == PGRES_COMMAND_OK);
		PQclear(result);

		if (check_applied)
		{
			/*printf("Checking standby...\n");*/
			snprintf(buffer, sizeof(buffer), "SELECT n FROM counter");
			result = PQexec(standby, buffer);
			assert(PQresultStatus(result) == PGRES_TUPLES_OK);
			assert(PQntuples(result) == 1);
			assert(atoi(PQgetvalue(result, 0, 0)) == i);
			PQclear(result);
		}
	}
	exit(0);
}
