/* quirc -- QR-code recognition library
 * Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <ctype.h>
#include <quirc.h>
#include <jpeglib.h>
#include <setjmp.h>
#include <time.h>
#include "dbgutil.h"

static int want_verbose = 0;
static int want_cell_dump = 0;

#define MS(ts) (unsigned int)((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000))

static struct quirc *decoder;

struct result_info {
	int		file_count;
	int		id_count;
	int		decode_count;

	unsigned int	load_time;
	unsigned int	identify_time;
	unsigned int	total_time;
};

static void print_result(const char *name, struct result_info *info)
{
	puts("----------------------------------------"
	     "---------------------------------------");
	printf("%s: %d files, %d codes, %d decoded (%d failures)",
	       name, info->file_count, info->id_count, info->decode_count,
	       (info->id_count - info->decode_count));
	if (info->id_count)
		printf(", %d%% success rate",
		       (info->decode_count * 100 + info->id_count / 2) /
			info->id_count);
	printf("\n");
	printf("Total time [load: %u, identify: %u, total: %u]\n",
	       info->load_time,
	       info->identify_time,
	       info->total_time);
	if (info->file_count)
		printf("Average time [load: %u, identify: %u, total: %u]\n",
		       info->load_time / info->file_count,
		       info->identify_time / info->file_count,
		       info->total_time / info->file_count);
}

static void add_result(struct result_info *sum, struct result_info *inf)
{
	sum->file_count += inf->file_count;
	sum->id_count += inf->id_count;
	sum->decode_count += inf->decode_count;

	sum->load_time += inf->load_time;
	sum->identify_time += inf->identify_time;
	sum->total_time += inf->total_time;
}

static int scan_file(const char *path, const char *filename,
		     struct result_info *info)
{
	int (*loader)(struct quirc *, const char *);
	int len = strlen(filename);
	const char *ext;
	struct timespec tp;
	unsigned int start;
	unsigned int total_start;
	int ret;
	int i;

	while (len >= 0 && filename[len] != '.')
		len--;
	ext = filename + len + 1;
	if (strcasecmp(ext, "jpg") == 0 || strcasecmp(ext, "jpeg") == 0)
		loader = load_jpeg;
	else if (strcasecmp(ext, "png") == 0)
		loader = load_png;
	else
		return 0;

	(void)clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
	total_start = start = MS(tp);
	ret = loader(decoder, path);
	(void)clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
	info->load_time = MS(tp) - start;

	if (ret < 0) {
		fprintf(stderr, "%s: load failed\n", filename);
		return -1;
	}

	(void)clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
	start = MS(tp);
	quirc_end(decoder);
	(void)clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
	info->identify_time = MS(tp) - start;

	info->id_count = quirc_count(decoder);
	for (i = 0; i < info->id_count; i++) {
		struct quirc_code code;
		struct quirc_data data;

		quirc_extract(decoder, i, &code);

		if (!quirc_decode(&code, &data))
			info->decode_count++;
	}

	(void)clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp);
	info->total_time += MS(tp) - total_start;

	printf("  %-30s: %5u %5u %5u %5d %5d\n", filename,
	       info->load_time,
	       info->identify_time,
	       info->total_time,
	       info->id_count, info->decode_count);

	if (want_cell_dump || want_verbose) {
		for (i = 0; i < info->id_count; i++) {
			struct quirc_code code;

			quirc_extract(decoder, i, &code);
			if (want_cell_dump) {
				dump_cells(&code);
				printf("\n");
			}

			if (want_verbose) {
				struct quirc_data data;
				quirc_decode_error_t err =
					quirc_decode(&code, &data);

				if (err) {
					printf("  ERROR: %s\n\n",
					       quirc_strerror(err));
				} else {
					printf("  Decode successful:\n");
					dump_data(&data);
					printf("\n");
				}
			}
		}
	}

	info->file_count = 1;
	return 1;
}

static int test_scan(const char *path, struct result_info *info);

static int scan_dir(const char *path, const char *filename,
		    struct result_info *info)
{
	DIR *d = opendir(path);
	struct dirent *ent;
	int count = 0;

	if (!d) {
		fprintf(stderr, "%s: opendir: %s\n", path, strerror(errno));
		return -1;
	}

	printf("%s:\n", path);

	while ((ent = readdir(d))) {
		if (ent->d_name[0] != '.') {
			char fullpath[1024];
			struct result_info sub;

			snprintf(fullpath, sizeof(fullpath), "%s/%s",
				 path, ent->d_name);
			if (test_scan(fullpath, &sub) > 0) {
				add_result(info, &sub);
				count++;
			}
		}
	}

	closedir(d);

	if (count > 1) {
		print_result(filename, info);
		puts("");
	}

	return count > 0;
}

static int test_scan(const char *path, struct result_info *info)
{
	int len = strlen(path);
	struct stat st;
	const char *filename;

	memset(info, 0, sizeof(*info));

	while (len >= 0 && path[len] != '/')
		len--;
	filename = path + len + 1;

	if (lstat(path, &st) < 0) {
		fprintf(stderr, "%s: lstat: %s\n", path, strerror(errno));
		return -1;
	}

	if (S_ISREG(st.st_mode))
		return scan_file(path, filename, info);

	if (S_ISDIR(st.st_mode))
		return scan_dir(path, filename, info);

	return 0;
}

static int run_tests(int argc, char **argv)
{
	struct result_info sum;
	int count = 0;
	int i;

	decoder = quirc_new();
	if (!decoder) {
		perror("quirc_new");
		return -1;
	}

	printf("  %-30s  %17s %11s\n", "", "Time (ms)", "Count");
	printf("  %-30s  %5s %5s %5s %5s %5s\n",
	       "Filename", "Load", "ID", "Total", "ID", "Dec");
	puts("----------------------------------------"
	     "---------------------------------------");

	memset(&sum, 0, sizeof(sum));
	for (i = 0; i < argc; i++) {
		struct result_info info;

		if (test_scan(argv[i], &info) > 0) {
			add_result(&sum, &info);
			count++;
		}
	}

	if (count > 1)
		print_result("TOTAL", &sum);

	quirc_destroy(decoder);
	return 0;
}

int main(int argc, char **argv)
{
	int opt;

	printf("quirc test program\n");
	printf("Copyright (C) 2010-2012 Daniel Beer <dlbeer@gmail.com>\n");
	printf("Library version: %s\n", quirc_version());
	printf("\n");

	while ((opt = getopt(argc, argv, "vd")) >= 0)
		switch (opt) {
		case 'v':
			want_verbose = 1;
			break;

		case 'd':
			want_cell_dump = 1;
			break;

		case '?':
			return -1;
		}

	argv += optind;
	argc -= optind;

	return run_tests(argc, argv);;
}
