#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <libmegapixels.h>
#include "config.h"
#include "util.h"

#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
#ifndef DATADIR
#define DATADIR "/usr/share"
#endif

static int
has_access_to_file(const char *conffile, int print)
{
	if (print) {
		printf("- %s\n", conffile);
	}
	if (access(conffile, F_OK) != -1) {
		return 1;
	}
	return 0;
}

static int
find_device_by_model(ssize_t maxlen, char *conffile, char *model, int print)
{
	const char *home = getenv("HOME");
	char *config_home = getenv("XDG_CONFIG_HOME");
	int fch = 0;
	if ((config_home == NULL || config_home[0] == '\0') && home != NULL) {
		config_home = mprintf("%s/.config", home);
		fch = 1;
	}
	// Check in XDG_CONFIG_HOME/megapixels/config
	snprintf(conffile, maxlen, "%s/megapixels/config/%s.conf", config_home, model);
	if (has_access_to_file(conffile, print)) {
		if(fch) {
			free(config_home);
		}
		return 1;
	}

	// Check fixed paths
	static const char *paths[] = {
		"config/%s.conf",
		SYSCONFDIR "/megapixels/config/%s.conf",
		DATADIR "/megapixels/config/%s.conf",
		NULL
	};
	for (const char **fmt = paths; *fmt; fmt++) {
		snprintf(conffile, maxlen, *fmt, model);
		if (has_access_to_file(conffile, print)) {
			if(fch) {
				free(config_home);
			}
			return 1;
		}
	}
	if (print) {
		printf("no config for '%s'\n", model);
	}
	if(fch) {
		free(config_home);
	}
	return 0;
}

int
libmegapixels_find_config_verbose(ssize_t maxlen, char *configfile, int print)
{
	long size = 0;
	char *compatible = mread("/proc/device-tree/compatible", &size);
	if(compatible == NULL) {
		if(print) {
			printf("Cannot open /proc/device-tree/compatible\n");
		}
		return 0;
	}
	char *modelptr = compatible;
	while ((modelptr - compatible) < size) {
		if (find_device_by_model(maxlen, configfile, modelptr, print)) {
			free(compatible);
			return 1;
		}
		modelptr += strlen(modelptr)+1;
	}
	free(compatible);
	return 0;
}

int
libmegapixels_find_config(ssize_t maxlen, char *configfile)
{
	return libmegapixels_find_config_verbose(maxlen, configfile, 0);
}
