#include <string.h>

#ifdef FTDI_LIBSYSFS
#include <sysfs/libsysfs.h>
#endif

#include <errno.h>

#include "orcd.h"
#include "logutils.h"

#define LOGCHANNEL "FTDI"

#define BUFSIZE 1024

int ftdi(orcd_t *orcd)
{
#ifdef FTDI_LIBSYSFS
	char *devpath=orcd->opt->getOptionString("device");
	char rootpath[BUFSIZE];
	char buf[BUFSIZE];

	sysfs_get_mnt_path(rootpath, BUFSIZE);

	// find our class path via udevinfoi
	snprintf(buf, BUFSIZE, "udevinfo -q path -n %s", devpath);
	
	FILE *f=popen(buf, "r");
	if (f==NULL)
	{
		log(LOG_ERROR,"Couldn't query udevinfo: %s",buf);
		return EXIT_FAILURE;
	}
	fgets(buf, 1000, f);
	pclose(f);

	// construct the sysfs path
	snprintf(buf, 1024, "%s/%s", rootpath, buf);

	// open the sysfs class object
	struct sysfs_class_device *scd=sysfs_open_class_device_path("/sys/class/tty/ttyUSB0");
	if (scd==NULL)
	{
		perror("sysfs");
		return EXIT_FAILURE;
	}
	
	// look up the device path
	struct sysfs_device *sd=sysfs_get_classdev_device(scd);

	if (!sd)
	{
		log(LOG_ERROR, LOGCHANNEL, "FTDI: path lookup failed: %s", strerror(errno));
		return EXIT_FAILURE;
	}
	
	// our object is up two levels of abstraction: not the USB
	// device itself, not the USB serial layer
	sd=sysfs_get_device_parent(sd);
	if (!sd)
	{
		log(LOG_ERROR, LOGCHANNEL, "FTDI: get parent (1) failed: %s", strerror(errno));
		return EXIT_FAILURE;
	}
	sd=sysfs_get_device_parent(sd);
	if (!sd)
	{
		log(LOG_ERROR, LOGCHANNEL, "FTDI: get parent (2) failed: %s", strerror(errno));
		return EXIT_FAILURE;
	}

	// find our attribute, "event_char"
	struct sysfs_attribute *eventcharattr=sysfs_get_device_attr(sd, "event_char");
	if (eventcharattr==NULL)
	{
		log(LOG_WARN,LOGCHANNEL,"FTDI: attribute event_char not supported: %s.", strerror(errno));
	}
	else
	{
		// Set the event_char to 0xEE, or 238, with the "on" flag (256)
		if (sysfs_write_attribute(eventcharattr,"494",3))
			log(LOG_ERROR,LOGCHANNEL,"FTDI: couldn't write attribute event_char");
		sysfs_close_attribute(eventcharattr);
	}
	
	// These seem to cause seg faults. What's up with that??
	//      sysfs_close_device(sd);
	//      sysfs_close_class_device(scd);

#endif
	// normal exit
	return 0;
}
