/*
    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.
*/

#ifndef MAIN_CPP
#define MAIN_CPP
#include "matrices_all.h"

void helpMsg(char* av)
{
	std::cout<<"Program computing histogram of values and printing it to standard output\n"
			<<"Runtime format: "<<av<<" in_matrix step_value format\n"
			<<"Acceptable formats: textfile, supermatrix\n";
}
/**
  * Function creating value histogram from CRS matrix
  * \param hist Output vector with histogram
  * \param fileName Path to CRS matrix
  * \param step Step for building histogram
  */
void createHistrogramSupermatrix(std::vector<size_t> &hist,char* fileName, double step)
{

	Matrices::CRSMatrixPtr inMatrix = Matrices::IO::ReadCRSFromSingleFile(fileName,"in_matrix");
	int counter=0;
	for(size_t i=0;i<inMatrix->NumberOfRows();i++)
	{

		Matrices::STDoubleMapPtr rowValues = inMatrix->GetCompressedRow(i)->GetValues();
		if(rowValues->size()!=0)
		{
			for(Matrices::STDoubleMapIter iter = rowValues->begin();iter!=rowValues->end();++iter)
			{
				counter++;
				int histIndex = ceil(iter->second / step) - 1;
				hist[histIndex]=hist[histIndex]+1;
			}
		}
	}
}
/**
  * Function creating value histogram from textfile
  * \param hist Output vector with histogram
  * \param fileName Path to text file with matrix
  * \param step Step for building histogram
  */
void createHistrogramTextfile(std::vector<size_t> &hist,char* fileName, double step)
{
	std::ifstream file(fileName);
	if(!file)
		throw std::runtime_error("Cannot open input file!\n");
	std::string line;
	size_t row_index=-1;
	size_t line_no=0;
	size_t rows_processed=0;
	while( std::getline(file, line) )
	{
		boost::trim_right(line);
		if( line.size() ==0 )
			continue;

		if(isdigit(line[0]))
		{// new row
			row_index = boost::lexical_cast<size_t>(line);
			rows_processed++;

		}
		else
		{// in the middle of a row
			std::vector<std::string> tokens;
			boost::split(tokens, line, boost::is_any_of(" \t"));
			if(tokens.size() != 3)
			{
				std::cerr << "Error in line " << line_no << std::endl;
				continue;
			}
			size_t col = boost::lexical_cast<size_t>(tokens[1]);


			if(col == row_index)
				continue; // skipping sim(x,x)

			double val = boost::lexical_cast<double>(tokens[2]);
			int histIndex = ceil(val / step) - 1;
			hist[histIndex]=hist[histIndex]+1;

		}
		++line_no;

		if(line_no % 1000000 == 0)
			std::cout << "Line " << line_no / 1000000 << "M Rows processed: " << rows_processed <<std::endl;
	}
}

int main(int ac, char**av)
{
	Matrices::init_logging();
	if(ac>0 && (strcmp(av[1],"--help")==0))
	{
		helpMsg(av[0]);
		return 1;
	}
	if(ac!=4)
	{
		helpMsg(av[0]);
		throw std::runtime_error("Invalid number of parameters!\n");
		return -1;
	}

	double step = atof(av[2]);
	if(step<=0 || step >1)
		throw std::runtime_error("Invalid step!");
	std::vector<size_t> histogram;
	for(int i=0;i*step<1;i++)
		histogram.push_back(0);

	if(strcmp(av[3],"supermatrix")==0)
		createHistrogramSupermatrix(histogram,av[1],step);
	else if(strcmp(av[3],"textfile")==0)
		createHistrogramTextfile(histogram,av[1],step);
	else
		throw std::runtime_error("Unknown file format!\n");

	std::cout<<"Printing histogram...\n";
	int counter=0;
	for(size_t i=0;i<histogram.size();i++)
	{
		if(histogram[i]>0)
		{
			std::cout<<step*i<<" to "<< step*(i+1)<<": "<<histogram[i]<<std::endl;
			counter+=histogram[i];
		}
	}
	std::cout<<"Counter: "<<counter<<std::endl;
	return 0;
}

#endif // MAIN_CPP
