/* Eric Knibbe, David Streng
*  CS 232
*  Project 3
*/

#ifndef DESHELL_CPP
#define DESHELL_CPP
#include "DEShell.h"

// constructor
DEShell::DEShell() {
    //shell initialization
}
// run - create a Prompt pmt and execute any commands issued to it
void DEShell::run() {
	Prompt pmt;
	Path pth;
	string instring, cmd;
	int pid = 0, check;
	cout << pmt.get();
	getline(cin, instring);
	istringstream iss(instring, istringstream::in);
	CommandLine cl(iss);
	
	if (string(cl.getCommand()) == "exit"){}
	else if (string(cl.getCommand()) == "cd")
	{
		check = chdir(cl.getArgVector(1));
		if (check != 0)
		{
			cout << "\nInvalid Directory\n";
			run();		//call run() whenever a failure occurs
		}
		else
		{
			pmt.setPrompt();
			run();
		}
	}
	else if (!(string(cl.getCommand()).empty()))
	{
		check = pth.find(cl.getCommand());
		if (check == -1)
		{
			cout << "Invalid command.\n";
			run();
		}
		else
		{
			cmd = pth.getDirectory(check) + '/' + cl.getArgVector(0);
			pid = fork();
			if (pid == 0) //run child code
			{
				execve(cmd.c_str(), cl.getArgVector(), NULL);
			}
			else if (pid < 0)
			{
				cout << "Error Forking.\n";
				run();
			}
			else
			{
				//if there is no ampersand, wait until the process finishes
				//before continuing, otherwise make a new copy of run to continue 
				//running while the process executes in the "background".
				if (cl.noAmpersand()) 
				{
					waitpid(pid, 0 , 0);
					run();
				}
				else
				{
					run();
				}
			}
		}
	}
	else
	{
		run();
	}
}

#endif

