/*
    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 <boost/shared_ptr.hpp>
#include <boost/lexical_cast.hpp>
#include <vector>
#include <string>
#include <stdexcept>
#include <map>
#include <iostream>

void SaveResultFile(const std::string & clutoFile, const std::string & contextsPath, const std::string & outputPath);
template <class T>
boost::shared_ptr<std::vector<T> > ReadVector(const std::string & filename);

using namespace std;

int main(int argc, char **argv)
{
	if (argc != 4)
	{
		cout << "Usage: saver clutofile contextfile outputfile" << endl;
		return 1;
	}
	SaveResultFile(argv[1], argv[2], argv[3]);
	return 0;
}

void SaveResultFile(const string & clutoFile, const string & contextsPath, const string & outputPath)
{
	ofstream out_stream(outputPath.c_str());
	if(!out_stream)
		throw runtime_error("Error writing to file " + outputPath);

	boost::shared_ptr<vector<int> > clusters;
	boost::shared_ptr<vector<string> > contexts;

	clusters = ReadVector<int>(clutoFile);
	contexts = ReadVector<string>(contextsPath);

	if (clusters->size() != contexts->size())
		throw runtime_error("Different sizes of files: " + clutoFile + " " + contextsPath);

	map<int, vector<size_t> > contextInCluster;

	for (size_t i = 0; i < clusters->size(); ++i)
	{
		int currentCluster = (*clusters)[i];
		if (currentCluster < 0)
			continue;

		if (contextInCluster.find(currentCluster) == contextInCluster.end())
			contextInCluster.insert(make_pair(currentCluster, vector<size_t>()));

		contextInCluster[currentCluster].push_back(i);
	}

	map<int, vector<size_t> >::iterator iter = contextInCluster.begin();

	for (; iter != contextInCluster.end(); ++iter)
	{
		out_stream << "Cluster: " << iter->first << endl;
		for (size_t j = 0; j < iter->second.size(); ++j)
		{
			out_stream << (iter->second[j]+1) << ": " << contexts->at(iter->second[j]) << endl;
		}
	}
	out_stream.close();
}

template <class T>
boost::shared_ptr<vector<T> > ReadVector(const string & filename)
{
	boost::shared_ptr<vector<T> > result(new vector<T>());

	ifstream in_stream(filename.c_str());
	if(!in_stream)
		throw runtime_error("Error reading from file " + filename);

	string line;

	while (getline(in_stream, line, '\n'))
	{
		T elem = boost::lexical_cast<T>(line);
		result->push_back(elem);
	}
	return result;
}
