/*
 * src/test/examples/testlibpq.c
 *
 *
 * testlibpq.c
 *
 *      Test the C version of libpq, the PostgreSQL frontend library.
 */
#include <stdio.h>
#include <stdlib.h>
#include <postgresql/libpq-fe.h>
#include <openssl/ssl.h>
#include <dlfcn.h>

typedef PGconn* (*PQconnectdb_func)(const char *conninfo);
typedef void (*PQfinish_func)(PGconn *conn);
typedef ConnStatusType (*PQstatus_func)(const PGconn *conn);
typedef char* (*PQerrorMessage_func)(const PGconn *conn);


static void
exit_nicely(PGconn *conn, PQfinish_func finish_func)
{
    finish_func(conn);
    exit(1);
}

// Dummy to force linking of openssl
void dummy_openssl() {
    SSL_library_init();
}

int
main2(int argc, char **argv)
{
    const char *conninfo;
    PGconn     *conn;
    PGresult   *res;
    int         nFields;
    int         i,
                j;
    void *handle;
    PQconnectdb_func conn_func;
    PQfinish_func finish_func;
    PQstatus_func status_func;
    PQerrorMessage_func errorMessage_func;
    char* error;

    handle = dlopen("libpq.so", RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "Fehler beim Laden: %s\n", dlerror());
        return 1;
    }
    
    conn_func = (PQconnectdb_func)dlsym(handle, "PQconnectdb");
    error = dlerror();
    if (error != NULL) {
        fprintf(stderr, "error loading function: %s\n", error);
        dlclose(handle);
        return 1;
    }
    finish_func = (PQfinish_func)dlsym(handle, "PQfinish");
    error = dlerror();
    if (error != NULL) {
        fprintf(stderr, "error loading function: %s\n", error);
        dlclose(handle);
        return 1;
    }
    status_func = (PQstatus_func)dlsym(handle, "PQstatus");
    error = dlerror();
    if (error != NULL) {
        fprintf(stderr, "error loading function: %s\n", error);
        dlclose(handle);
        return 1;
    }
    errorMessage_func = (PQerrorMessage_func)dlsym(handle, "PQerrorMessage");
    error = dlerror();
    if (error != NULL) {
        fprintf(stderr, "error loading function: %s\n", error);
        dlclose(handle);
        return 1;
    }

    /*
     * If the user supplies a parameter on the command line, use it as the
     * conninfo string; otherwise default to setting dbname=postgres and using
     * environment variables or defaults for all other connection parameters.
     */
    if (argc > 1)
        conninfo = argv[1];
    else
        conninfo = "dbname = postgres";

    /* Make a connection to the database */
    conn = conn_func(conninfo);

    /* Check to see that the backend connection was successfully made */
    if (status_func(conn) != CONNECTION_OK)
    {
        fprintf(stderr, "%s", errorMessage_func(conn));
        exit_nicely(conn, finish_func);
    }

    /* close the connection to the database and cleanup */
    finish_func(conn);
    /* unload libpq */
    dlclose(handle);

    return 0;
}

int
main(int argc, char **argv) {
	int i=0;
	dummy_openssl();
	for (i=0; i < 229; i++) {
		printf("%d\n", i);
		/* will fail at i==127 */
		main2(argc, argv);
	}
}

