#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <semaphore.h>
#include <fcntl.h>
#include <time.h>
#include <wiringPi.h>
#include <pthread.h>
#include <errno.h>

#define	PIN	0

int busy_flag;
unsigned int pipe1;
unsigned int pipe2;
unsigned int brew_log;
char rec_pipe_message[100];
char log_message[100];
char reply_message[100];
char* tokens[2];
char* date_time;
pthread_t thread;
sem_t sem;
time_t rawtime;
struct tm* timeinfo;

void check_fifo()
{
	while(1)
	{
		bzero(rec_pipe_message, sizeof(rec_pipe_message));
		bzero(reply_message, sizeof(reply_message));
		bzero(log_message, sizeof(log_message));
		
		/* When pipe is read correctly */
		if(read(pipe1, &rec_pipe_message, sizeof(rec_pipe_message)) >= 0)
		{	
			tokens[0] = strtok(rec_pipe_message, " ");
			tokens[1] = strtok(NULL, " ");
			
			time(&rawtime);
			timeinfo = localtime(&rawtime);
			
			date_time = asctime(timeinfo);
			date_time[strlen(date_time) - 1] = '\0';
			
			strcat(log_message, date_time);
			strcat(log_message, "\t");
			strcat(log_message, tokens[0]);
			
			lseek(brew_log, 0, SEEK_END);
			
			switch(atoi(tokens[1]))
			{
				case 0:
					strcat(log_message, "\tCoffee NOT made\n");
					write(brew_log, log_message, sizeof(log_message));
					break;
				case 1:
					if(!busy_flag)
					{
						sem_post(&sem);
						
						strcat(log_message, "\tCoffee WAS made\n");
						strcat(reply_message, ", thanks for your message. Your coffee is being brewed!\n");
						
						write(brew_log, log_message, sizeof(log_message));
						
						if(write(pipe2, &reply_message, sizeof(reply_message)) != sizeof(reply_message))
							printf("Error writing to NAMED PIPE\n");
					}
					else
					{
						strcat(log_message, "\tCoffee NOT made; Brewing in progress\n");
						strcat(reply_message, ", another cup of coffee is being brewed. Try again later!\n");
						
						write(brew_log, log_message, sizeof(log_message));
						
						if(write(pipe2, &reply_message, sizeof(reply_message)) != sizeof(reply_message))
							printf("Error writing to NAMED PIPE\n");
					}
					break;
				case 2:
					strcat(log_message, "\tUKNOWN NUMBER No coffee\n");
					write(brew_log, log_message, sizeof(log_message));
					break;
			}
		}
		/* When pipe was not read correctly */
		else
		{
			printf("Error reading NAMED PIPE\n");
			pthread_exit(0);
		}
	}
}

int main (void)
{	
	/* Sets up WiringPi library to use and sets pin mode */
	wiringPiSetup ();
	pinMode(PIN, OUTPUT);
	
	/* Initializes semaphore */
	sem_init(&sem, 0, 0);
	
	/* Sets busy flag to 0 */
	busy_flag = 0;
	
	/* Checks to see if pipe1 opens properly */
	if((pipe1 = open("pipe1", O_RDONLY)) < 0){
		printf("Error opening NAMED PIPE 1\n");
		return -1;
	}
	
	/* Checks to see if pipe2 opens properly */
	if((pipe2 = open("pipe2", O_WRONLY)) < 0){
		printf("Error opening NAMED PIPE 1\n");
		return -1;
	}
		
	if((brew_log = open("brew.log", O_RDWR | O_CREAT)) < 0){
		printf("Error opening BREW LOG\n");
		return -1;
	}
	
	if(pthread_create(&thread, NULL, (void*)&check_fifo, NULL) == 0)
	{
		while(1)
		{
			sem_wait(&sem);
			busy_flag = 1;
			
			digitalWrite (PIN, HIGH);	// On
			delay(500);					// mS
			digitalWrite(PIN, LOW);		// Off
			delay(30000);				// 90000   = 1:30
										// 180000  = 3:00
										// 1200000 = 20:00			

			digitalWrite (PIN, HIGH);	// On
			delay(500);					// mS
			digitalWrite(PIN, LOW);		// Off
			
			busy_flag = 0;
		}
	}
	else
		printf("Error - Failed to create Pthread\n");
	
	return 0;
}
