/*
    Copyright (C) 2012 Bartosz Broda, Jacek Bochenek, Łukasz Biłeńkij, 
    Damian Jaworski, Wojciech Mazur, Dominik Piasecki, Maciej Piasecki, 
    Radosław Ramocki
    
    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.

    This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. 

    See the LICENSE and COPYING files for more details.
*/

#include <fstream>
#include <string>
#include <vector>
#include <stdexcept>
#include <cstring>
#include <iostream>
#include <stdlib.h>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <sstream>

void helpMsg(char* av)
{
	std::cout<<"Architect runner\n"
			<<"Runtime format: "<<av<<" num_of_tasks mpi_hostfile architect file_with_configs\n";

}

int main(int ac,char**av)
{
	if(ac>0 && strcmp(av[1],"--help")==0)
	{
		helpMsg(av[0]);
		return 1;
	}
	if(ac!=5)
	{
		helpMsg(av[0]);
		throw std::runtime_error("Invalid number of parameters\n");
		return -1;
	}
	int numOfTasksAtOnce = atoi(av[1]);
	std::string mpi_hostfile(av[2]);
	std::string architect(av[3]);
	std::ifstream configFile(av[4]);
	if(!configFile)
	{
		throw std::runtime_error("Cannot open config file!\n");
	}
	std::vector<std::string> jobs;
	std::vector<std::string> files_to_check;
	std::string line;
	std::vector<std::string> tokens;
	while(std::getline(configFile,line))
	{
		boost::split(tokens, line, boost::is_any_of(";"));
		jobs.push_back(tokens[0]);
		files_to_check.push_back(tokens[1]);
	}
	int jobsDone = 0;
	std::vector<int> jobsActive;
	int jobIterator=0;
	while(jobsDone<(int)jobs.size())
	{
		while((int)jobsActive.size()<numOfTasksAtOnce && jobIterator<(int)jobs.size())
		{
			std::stringstream ss;
			ss<<"mpirun -n 7 --hostfile "<<mpi_hostfile<<" "<<architect<<" --cfg-file "<<jobs[jobIterator]<<"&";
			std::string command = ss.str();
			int returnValue = system(command.c_str());
			if(returnValue!=0)
				std::cout<<"Return value from system wasnt 0!\n";
			jobsActive.push_back(jobIterator);
			std::cout<<"Run task no "<<jobIterator<<", command: "<<command<<std::endl;
			jobIterator++;
		}
		for(int i=0;i<(int)jobsActive.size();i++)
		{
			if(boost::filesystem::exists(files_to_check[jobsActive[i]]))
			{
				std::cout<<"Finished task no"<<jobsActive[i]<<std::endl;
				jobsActive.erase(jobsActive.begin()+i);
				jobsDone++;
				i--;
			}
		}
		sleep(10);
	}

	return 0;

}
