/*
    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 "matrices_all.h"
#include <algorithm>
#include <time.h>

void get_most_frequent_words(Matrices::SuperMatrixPtr pMatrix, std::set<size_t> &output, size_t sample_size,
							 size_t mintf = 1000)
{
	srand ( unsigned ( time (NULL) ) );
	Matrices::FeatureVectorPtr pRowFeatures = pMatrix->GetRowFeatures();
	std::vector<size_t> row_indices;
	for( size_t no = 0; no < pRowFeatures->size(); ++no)
	{
		const Matrices::Feature & feature = (*pRowFeatures)[no];
		if( feature.GetTermFrequency() > mintf)
			row_indices.push_back(no);
	}


	std::random_shuffle(row_indices.begin(), row_indices.end());

	size_t to_end = row_indices.size() < sample_size ? row_indices.size() :sample_size;

	std::copy(row_indices.begin(), row_indices.begin()+to_end, std::insert_iterator<std::set<size_t> >(output, output.begin()));

}



int main(int ac, char **av)
{
	Matrices::init_logging();
	if(ac != 7)
	{
		std::cerr << "MSampler. Author: Bartosz Broda, bartosz.broda@gmail.com\n"
				<< "Draws rasample of rows from a matrix.\n"
				<< "Usage:\n\tmsampler matrix_dir matrix_name sample_size mintf output_dir output_name\n\n";
		return -1;
	}

	std::string mdir = av[1];
	std::string mname = av[2];

	size_t sample_size = boost::lexical_cast<size_t>(av[3]);
	size_t mintf = boost::lexical_cast<size_t>(av[4]);

	std::string outdir = av[5];
	std::string outname = av[6];


	Matrices::SuperMatrixPtr pInputMatrix = Matrices::IO::LoadSuperMatrix(mdir, mname, false, true);

	std::set<size_t> indices;
	get_most_frequent_words(pInputMatrix, indices, sample_size, mintf);

	std::set<size_t> row_indices_to_erase;

	for(size_t i = 0; i < pInputMatrix->NumberOfRows(); ++i)
		if(indices.count(i) == 0)
			row_indices_to_erase.insert(i);

	std::set<size_t> column_indices_to_erase;
	for(size_t i = 0; i < pInputMatrix->NumberOfColumns(); ++i)
		column_indices_to_erase.insert(i);

	for(std::set<size_t>::iterator iter = indices.begin(); iter != indices.end(); ++iter)
	{
		Matrices::CompressedVectorPtr pRow = pInputMatrix->GetRow(*iter);
		Matrices::STDoubleMapPtr pValues = pRow->GetValues();
		for(std::map<size_t, double>::iterator col_iter =  pValues->begin(); col_iter != pValues->end(); ++col_iter)
			column_indices_to_erase.erase(col_iter->first);
	}

	Matrices::SuperMatrixPtr pOutputMatrix = Matrices::FilterSuperMatrix(pInputMatrix, row_indices_to_erase,
																   column_indices_to_erase);

	pOutputMatrix->SetNewName(outname);

	std::cout << "Writing output matrix (" << outname << ") to " << outdir << std::endl;
	Matrices::IO::WriteSuperMatrix(pOutputMatrix, outdir);

	std::cout << "All done" << std::endl;
	return 0;
}
