/*
LinkedList* getRedirectionQueue()
	Description:
		Creates a queue that can be iterated through using _next()
	args:
		char** args
			Array of tokens
	return:
		LinkedList reverse so that _next() iterates through in order of args.
		Args are grouped with redirects in the middle of them.
		Returns NULL if not a proper redirection.
*/
LinkedList* getRedirectionQueue(char** args){
	if(!isProperRedirection(args)){
		return NULL;
	}
	LinkedList* stack = LinkedList_init();
	LinkedList* output = LinkedList_init();

	int j = 0;
	char** buffer = calloc(128, sizeof(*buffer));
	for(int i = 0; args[i] != NULL; i++){
		if(args[i][0] != '>' && args[i][0] != '<'){
			buffer[j] = args[i];					//Start collecting args
			j++;
		}else{										//Redirect detected. Queue.
			LinkedList_queue(stack, buffer);
			
			char** redirect = calloc(1,sizeof(*redirect));			//Add the redirect symbol to the queue
			redirect[0] = args[i];
			LinkedList_queue(stack, redirect);
			
			j = 0;
			buffer = calloc(128, sizeof(*buffer));				//Make new args collector
		}
	}
	if(buffer){
		LinkedList_queue(stack, buffer);				//Edge case. Final queue
	}
	output = LinkedList_reverse(stack);				//Reverse stack to get queue
	LinkedList_free(stack);
	return output;
}
LinkedList* getPipeQueue(char** args){
	if(!isProperPipe(args)){
		return NULL;
	}
	LinkedList* stack = LinkedList_init();
	LinkedList* output = LinkedList_init();
	
	int j = 0;
	char** buffer = calloc(128, sizeof(*buffer));
	for(int i = 0; args[i] != NULL; i++){
		if(args[i][0] != '|'){
			buffer[j] = args[i];					//Start collecting args
			j++;
		}else{										//Pipe detected. Queue.
			LinkedList_queue(stack, buffer);
			
			char** pipeline = calloc(1,sizeof(*pipeline));			//Add the pipeline symbol to the queue
			pipeline[0] = args[i];
			LinkedList_queue(stack, pipeline);
			j = 0;
			buffer = calloc(128, sizeof(*buffer));				//Make new args collector
		}
	}
	if(buffer){
		LinkedList_queue(stack, buffer);				//Edge case. Final queue
	}
	output = LinkedList_reverse(stack);				//Reverse stack to get queue
	LinkedList_free(stack);
	
	return output;

}
/* initialize from file */
LinkedList*
LinkedList_initWithFile(LinkedList *self, char *fileName, void *(nodeBuilder)(void *))
{
	FILE *fileHandle;
	size_t lineLength;
	char *line;
	void *nodeData;

	if (!self) { return 0; }

	/* initialize defaults */
	LinkedList_init(self);

	/* populate list economy style */
	if ((fileHandle = fopen(fileName, "r")) == NULL) { return 0; }
	while ((line = fgetln(fileHandle, &lineLength)) != NULL) {
		if (line[0] == '#' || line[0] == '\n') { continue; }

		if (lineLength > MAX_LINE_BUFFER - 1) {
			nodeData = malloc(MAX_LINE_BUFFER);
			strncpy(nodeData, line, MAX_LINE_BUFFER - 1);
			strncpy(nodeData + MAX_LINE_BUFFER, "\0", 1);
		} else {
			nodeData = malloc(lineLength);
			strncpy(nodeData, line, lineLength - 1);
			strncpy(nodeData + lineLength, "\0", 1);
		}
		LinkedList_push(self, nodeBuilder(nodeData));
	}
	fclose(fileHandle);
	return self;
}
/* constructor w/ default initialize */
LinkedList*
LinkedList_new()
{
	LinkedList *self = LinkedList_alloc();
	return (self)
		? LinkedList_init(self)
		: NULL;
}