#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <signal.h>
#include <time.h>
#include <assert.h>

#include "csv.h"

static int
test(FILE *f)
{
	int line = 0;
	csv_t csv = { 0 };

	while ( csv_read(&csv, f) != -1 ) {
		++line;
	}

	return line;
}

static int
test_exception(FILE *f)
{
	int line = 0;
	csv_t csv[1];

	csv_init(csv);
	for ( int n; (n = csv_read(csv, f)) != -1; ) {
		if (++line == 500000) csv_field(csv, -1);
	}

	return line;
}

static void
my_signal_handler(int sig)
{
	if ( sig == SIGABRT ) {
		fprintf(stderr, "my_signal_handler!\n");
		exit(1);
	}
}

static int
test_exception_with_signal(FILE *f)
{
	void (*old_handler)(int) = signal(SIGABRT, my_signal_handler);

	int line = 0;
	csv_t csv[1];

	csv_init(csv);
	for ( int n; (n = csv_read(csv, f)) != -1; ) {
		if (++line == 500000) csv_field(csv, -1);
	}

	signal(SIGABRT, old_handler);

	return line;
}

static void
my_error_handler(csv_err_t csv_err, void *env)
{
	assert(env != NULL);

	fprintf(stderr, "my_error_handler: %s\n", csv_err_str(csv_err));
	longjmp(*((jmp_buf *) env), 1);
}

static int
test_exception_longjmp(FILE *f)
{
	/* start with default options */
	csv_options_t csv_options = csv_default_options;

	/* setup error handler */
	jmp_buf env;
	csv_options.cb_error = my_error_handler;
	csv_options.cb_error_arg = &env;

	/* setup csv-Object with custom options */
	csv_t csv[1];
	csv_init_opt(csv, &csv_options);

	if ( setjmp(env) == 0 ) {
		int line = 0;

		for ( int n; (n = csv_read(csv, f)) != -1; ) {
			// process data...
			if (++line == 500000) csv_field(csv, -1);
		}
		return line;
	}
	else {
		csv_cleanup(csv);
		return -1;
	}
}

int
main(void)
{
#if 0
	const char *names[] = { "Thomas \"DG\" Schmucker", "Andrea", "Markus", "Marion", NULL };

	csv_write(stdout, -1, names, NULL);
	csv_write(stdout,  0, names, NULL);
	csv_write(stdout,  1, names, NULL);
	csv_write(stdout,  2, names, NULL);
	csv_write(stdout,  3, names, NULL);
	csv_write(stdout,  4, names, NULL);
	csv_write(stdout,  5, names, NULL);
	return 0;
#endif

	FILE *in = fopen("500000 Records.csv", "r");
	if ( in == NULL ) {
		fprintf(stderr, "failed to open testfile...\n");
		return EXIT_FAILURE;
	}

	clock_t start = clock();

	int lines = test(in);
	(void) test_exception;
	(void) test_exception_with_signal;
	(void) test_exception_longjmp;

	clock_t end = clock();

	fclose(in);

	printf("%d lines processed, duration: %.3lf sec\n", lines, ((double)(end - start)) / CLOCKS_PER_SEC);

	return EXIT_SUCCESS;
}
