#include "hw_impl_unix.h"
#include <sys/types.h>       
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <sys/ioctl.h>
#include <err.h>
#include <netinet/in.h>

#define DEFAULT_SOCKET "../../groundStation/virtquad.socket"
#define SOCKET_ENV "VIRT_QUAD_SOCKET"

static int backendSocket;
static int client;

int unix_uart_reset(struct UARTDriver *self) {
	char * backend_socket_path = DEFAULT_SOCKET;
	if (getenv(SOCKET_ENV)) {
		backend_socket_path = getenv(SOCKET_ENV);
	}

	/* Unlink if it exists */
	unlink(backend_socket_path);
	printf("using socket '%s'\n", backend_socket_path);

	/* Create socket */
	backendSocket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);


	/* Create sockaddr and bind */
	struct sockaddr_un sa;
	sa.sun_family = AF_UNIX;
	strncpy(sa.sun_path, backend_socket_path, strlen(backend_socket_path));
	sa.sun_path[strlen(backend_socket_path)+1] = '\0';
	if (bind(backendSocket, (struct sockaddr *) &sa, sizeof(sa))) {
		err(-1, "bind");
	}

	/* Listen */
	if (listen(backendSocket, 1)) {
		err(-1, "listen");
	}

	printf("Waiting for backend to connect\n");

	while (1) {
		client = accept(backendSocket, NULL, NULL);
		if (client > 0)
			break;
	}
	printf("backend connection found on socket %d.\n", client);
  return 0;
}

int unix_uart_write(struct UARTDriver *self, unsigned char c) {
	send(client, &c, 1, MSG_DONTWAIT);
	return 0;
}

int unix_uart_read(struct UARTDriver *self, unsigned char *c) {
	int bytes_available;
	ioctl(client,FIONREAD,&bytes_available);
	
	if (bytes_available > 0) {
		int bytes = recv(client, c, 1, 0);
		return 0;
	} else {
		return 1;
	}
}