//GREP.CPP
//COPYRIGHT EMILE J. KEITH 2014//
#include <iostream>
#include <string>
#include <boost/filesystem.hpp>//boost a collection of C++ open source libraries that are cross-platform compatible
#include <regex>
#include <boost/regex.hpp>//Has more features than the standard library regex
#include <fstream>
#include <exception>
#include <stdlib.h>
#include <iomanip>
using namespace std;
using namespace std::regex_constants;
using namespace boost::filesystem;
int main(int argc, char *argv[])
{
	
	if(argc<3)//Since the program name is the first function and there has to be an expression and another search parameter, there must be atlest 3 arguments on call
	{
		cout<<"No search area was provided!\n"<<endl;
		return 0;
	}
	else
	{
		bool iterateAllWithExtension=false;
		string searchPath,destination, extension;
		const string lastArgument(argv[argc-1]);
		if(lastArgument[lastArgument.find_last_of("/\\")+1]=='*' && lastArgument.find_last_of("/\\")+2==lastArgument.find_last_of("."))//If the char at the position after the last '\' or '/' in the provided path is a '*', and the following char is the last '.', signifying the start of the extension
		{
			searchPath=lastArgument.substr(0,lastArgument.find_last_of("/\\"));
			destination=lastArgument.substr(lastArgument.find_last_of("/\\")+1,string::npos);
			extension=destination.substr(destination.find_last_of('.'), string::npos);
			iterateAllWithExtension=true;
		} 
		if(iterateAllWithExtension)
		{
			path p(searchPath);//path class belonging to the boost library
			if(exists(p))
			{
			}
			else
			{
				cout<<"The file or directory provided does not exist\n";
				return 0;
			}
		}
		path p(argv[argc-1]);//This p is has a different scope than the previous, and it can be used as a name since the previous one is already out of scope
		if(exists(p) || exists(searchPath))//This needs to be fixed, because a .*.txt cannot exist
		{
			string fileName=p.filename().string();
			if(fileName.find(".")==0)//If the filename they provided begins with a fullstop, which you cannot do due to file naming restricitons, then you are trying to look for all files with a certain extension
			{
			}
			cout<<"Exists\n\n";
			if(is_regular_file(p))//function from the boost filesystem library
			{
				unsigned long endOfFile, currentPosition;
				ifstream file(argc[argv-1]);
				try
				{
					if(file.bad())
					{
						throw runtime_error("File is corrupted and cannot be opened for reading, program will now terminate\n");
					}
					else
					{
						file.seekg(0,ios::end);
						endOfFile=file.tellg();
						file.seekg(0,ios::beg);
					}
				}
				catch(runtime_error ex)//catches the runtime_error object thrown earlier
				{
					cerr<<ex.what()<<endl;
					exit(EXIT_FAILURE);//EXIT_FAILURE indicates that main must return 1 in windows, and whatever error terminating value in another operating system
				}
				//string sExpression(argv[argc-2]);
				const string toMatch=argv[argc-2];
				regex expression(toMatch);//the expression will be the second to last argument passed to main
				smatch match;//smatch is a typedef of match_results
				string currentLine;
				cout<<"In file "<<p.filename()<<" : \n";
				cout<<"__________________________________________"<<endl;
				unsigned short lineNumber=1;
				while(getline(file, currentLine))
				{
					currentPosition=file.tellg();
					if(currentPosition==endOfFile)
					{
						lineNumber=1;
						break;
					}
					else
					{
						if(regex_search(currentLine,expression))
							cout<<lineNumber<<"."<<currentLine<<"\n";
					}
					lineNumber++;
				}
			}
			else if(is_directory(p))
			{	
				cout<<"It is a directory"<<endl;
				return 0;
			}
		}
		else
		{
			cout<<"The file or directory provided does not exist\n";
			return 0;
		}
	}
	/*typedef bool bl;//Just playing with typedef
	bl tom=(bl)(string(argv[1])=="emile");
	cout<<argv[1]<<"\t"<<tom<<endl;
	if(tom)
		std::cout<<"I knew it was you"<<endl;
	else
		std::cout<<"why"<<endl;
	if(argc>2)
	{
		if(string(argv[2])=="-I")
		cout<<"It works"<<endl;
	}*/
	return 0;
}