int main()
{
  std::cout << "\n  Demonstrating BlockingQueue<std::string> Operation";
  std::cout << "\n ====================================================\n";

  BlockingQueue<std::string> q;
  TestQThread td(q);
  td.start();

  gCSLock<1> IOlock;  // global lock shares a static CS
  std::string msg;
  for(size_t i=0; i<25; ++i)
  {
    std::ostringstream convert;  // convert size_t value to string
    convert << i;
    msg = std::string("Msg #") + convert.str();
    q.enQ(msg);
    IOlock.lock();
    std::cout << "\n  main thread enQ'd " << msg.c_str();
    IOlock.unlock();
    ::Sleep(5);
  }
  q.enQ("quit");
  td.join();
  std::cout << "\n  parent exiting\n\n";
}
int main()
{
	title("Testing Sender", '=');
	try
	{
		Verbose v(true);
		SocketSystem ss;
		SocketListener sl(1000, Socket::IP6);
		BlockingQueue<Message> rQueue;
		BlockingQueue<Message> sQueue;
		Sender sd(&sQueue);

		string test = "Test Message";
		string fileName = "test1.txt";
		Message msg("STRING_HANDLING_REQUEST");
		msg.buildMessage(msg, 1000, 2000, test, test.size());

		displayMessage(msg, "Constructing");
		Message msg2("FILE_HANDLING_REQUEST");
		msg.buildMessage(msg2, 1000, 2000, fileName);
		sQueue.enQ(msg);
		sQueue.enQ(msg2);

		std::thread sThread(&Sender::getQueueMessage, Sender(&sQueue));
		sThread.join();
	}
	catch (std::exception& ex)
	{
		Verbose::show("  Exception caught:", always);
		Verbose::show(std::string("\n  ") + ex.what() + "\n\n");
	}
}
int main()
{
  std::cout << "\n  Demonstrating C++11 Blocking Queue";
  std::cout << "\n ====================================";

  BlockingQueue<std::string> q;
  std::thread t(test, &q);

  for(int i=0; i<15; ++i)
  {
    std::ostringstream temp;
    temp << i;
    std::string msg = std::string("msg#") + temp.str();
    {
      std::lock_guard<std::mutex> l(ioLock);
      std::cout << "\n   main enQing " << msg.c_str();
    }
    q.enQ(msg);
    std::this_thread::sleep_for(std::chrono::milliseconds(3));
  }
  q.enQ("quit");
  t.join();

  std::cout << "\n";
  std::cout << "\n  Making copy of BlockingQueue";
  std::cout << "\n ------------------------------";

  std::string msg = "test";
  q.enQ(msg);
  std::cout << "\n  q.size() = " << q.size();
  BlockingQueue<std::string> q2 = q;  // make default copy
  std::cout << "\n  q2.size() = " << q2.size();
  std::cout << "\n  q element = " << (msg = q.deQ());
  q.enQ(msg);
  std::cout << "\n  q2 element = " << q2.deQ() << "\n";

  std::cout << "\n  Assigning state of BlockingQueue";
  std::cout << "\n ----------------------------------";
  BlockingQueue<std::string> q3;
  q3 = q;
  std::cout << "\n  q.size() = " << q.size();
  std::cout << "\n  q3.size() = " << q3.size();
  std::cout << "\n  q element = " << q.deQ();
  q.enQ(msg);
  std::cout << "\n  q3 element = " << q3.deQ() << "\n";

  std::cout << "\n\n";
}
void ClientHandler::operator()(Socket& socket_)
{
	Display *disp = new Display();
	BlockingQueue<string> q_;
			while (true)
			{
				Receiver *rs = new Receiver();
				std::string command = socket_.recvString();
				q_.enQ(command);
				if (command.size() == 0)
					break;
				size_t size= q_.size();
				string ackmsg;
				for (size_t i = 0; i < size; i++)
				{
					command = q_.deQ();
					ackmsg = rs->start(command, socket_);
				}
				Sender *s = new Sender();
				if (ackmsg != "")
				{
					s->sendAck(socket_, ackmsg);
				}
		}
  
  disp->show("ClientHandler socket connection closing");
  socket_.shutDown();
  socket_.close();
  disp->show("ClientHandler thread terminating");

}
// Function for reterieving files which contains search text specified in the message
string Receiver::performTextSearch(string msg1, string &result)
{
	Display * disp = new Display();
	TextSearch *ts = new TextSearch();
	Message *m = new Message();
	BlockingQueue<std::string> resultfiles;
	std::vector<string> file_patterns, all_files;  
	string sstr = m->getmsgBody1(msg1), file_path = m->getFileName(msg1), filepattern = m->getPatterns(msg1), token, resultfiles1;
	disp->show("\n*******************************************\n");
	string prtmsg ="Performing Text Search for string: "+ sstr + "  on files with patterns " + filepattern+"\n";
	disp->show(prtmsg);
	std::istringstream ss(filepattern);
	while (std::getline(ss, token, ',')) 
	{
		file_patterns.push_back(token);
	}
	all_files = showFiles(file_path, file_patterns);
	for each (string file in all_files)
	{
		if (ts->search(sstr, file))
			resultfiles.enQ(file);
	}
	size_t vecsize = resultfiles.size();
	for (size_t i = 0; i < vecsize; i++)
	{
		resultfiles1 = resultfiles1 + resultfiles.deQ();
		resultfiles1.append(";");
	}
	disp->show("Sending Result File list to client \n");
	disp->show("*******************************************\n\n");
	Message *resmsg = new Message();
	Message orgmsg;
	orgmsg.setMessage(msg1);
	resmsg->setCommand("textsearch");
	resmsg->setFileAttrs(orgmsg.getFileName(msg1));
	resmsg->setsendAddr(orgmsg.getrecvAddr(msg1));
	resmsg->setrecAddr(orgmsg.getsendAddr(msg1));
	resmsg->setmsgBody(resultfiles1);
	result = resmsg->getMessage();
	return result;
}
//----< initialize client instance >-----------------
Client1::Client1(string sourceIP, int sourcePort, string destIP, int destPort,string filePath)
{
	title("Testing Socket Client", '=');
	displayPeerInformation("Client", sourceIP, sourcePort);
	try
	{
		Verbose v(true);
		SocketSystem ss;
		SocketListener sl(sourcePort, Socket::IP6);
		BlockingQueue<Message> rQueue; //receiving queue
		BlockingQueue<Message> sQueue; //sending queue
		Receiver rc(&rQueue,"");
		Sender sd(&sQueue);
		sl.start(rc);

		//string test = buildTestString();
		//Message msg("STRING_HANDLING_REQUEST");
		//msg.buildMessage(msg, sourcePort, destPort, test, test.size());

		//displayMessage(msg,"Constructing");
		Message msg2("FILE_HANDLING_REQUEST");
		msg2.buildMessage(msg2, sourcePort, destPort, filePath);
		//sQueue.enQ(msg);
		sQueue.enQ(msg2);

		std::thread sThread(&Sender::getQueueMessage, Sender(&sQueue));
		std::thread rThread(getQueueMessage, &rQueue, &sd);
		rThread.join();
		sThread.join();
	}
	catch (std::exception& ex)
	{
		Verbose::show("  Exception caught:", always);
		Verbose::show(std::string("\n  ") + ex.what() + "\n\n");
	}
}
void RequestProcessor::PostMessage(const Message& msg)
{
  inQ.enQ(msg);
}