/*
    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 "LDATransformation.h"
#include "../comparator_stdheaders.h"
#include "../matrices/io/defines.h"

#include <boost/filesystem.hpp>

static log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("SuperMatrix.comparator.transformations.LDATransformation"));

namespace smartcomparator
{
	namespace transformations
	{
		LDATransformation::LDATransformation(Matrices::SuperMatrixPtr m, size_t num_topics,
											 size_t passes, std::string temp_dir)
						:Transformation(m),
						m_topics(num_topics),
						m_passes(passes),
						m_pMatrix(m),
						m_sTempDir(temp_dir)
		{
			if(!atoi(GENSIM))
				throw std::runtime_error("gensim is not installed");
			m_FullTempPath=open_temp();

		}

		void LDATransformation::TransformMatrix()
		{
			if(m_topics>m_pMatrix->NumberOfColumns())
				throw std::runtime_error("Number of topics in LDAtransformation is bigger than number of columns in Super Matrix");
			Matrices::IO::WriteGensimMatrix(m_pMatrix, m_FullTempPath);
			RunGensim();
			Matrices::IO::ReadGensimToSuperMatrixFromFile(newcorpusFile, m_pMatrix);
			boost::filesystem::remove_all(boost::filesystem::path(m_FullTempPath));

		}

		void LDATransformation::RunGensim()
		{
			std::stringstream cmd;
			std::string corpusFile=m_FullTempPath+"/"+m_pMatrix->GetName()+"/"+GENSIM_MATRIX_NAME;
			newcorpusFile=m_FullTempPath+"/"+m_pMatrix->GetName()+"/"+GENSIM_NEW_MATRIX_NAME;
			std::string dictionaryFile=m_FullTempPath+"/"+m_pMatrix->GetName()+"/"+GENSIM_DICTIONARY_NAME;
			LOG4CXX_INFO(logger,"Computing LDA Model...");
			cmd << "python -c \"import gensim;from gensim.models import ldamodel;"
					"id2word=gensim.corpora.Dictionary.load_from_text('"<< dictionaryFile<< "'); "
					"mm = gensim.corpora.MmCorpus('"<< corpusFile <<"'); "
					"lda = ldamodel.LdaModel(corpus=mm, num_topics="<< m_topics<<", passes="<<m_passes<<");"
					"newcorpus = lda[mm];"
					"gensim.corpora.MmCorpus.serialize('"<<newcorpusFile<<"', corpus=newcorpus)"
					<< "\"";

			LOG4CXX_INFO(logger, cmd.str());
			int returnValue = system(cmd.str().c_str());
			if(returnValue!=0)
				LOG4CXX_ERROR(logger,"Return value from system: "<<returnValue);
			LOG4CXX_INFO(logger, "Computing LDA Model... done...");
		}

		std::string LDATransformation::open_temp()
		{
			boost::filesystem::path p(m_sTempDir);
			p /= "supermatrix_XXXXXX";
			std::string path = p.string();
			std::vector<char> dst_path(path.begin(), path.end());
			dst_path.push_back('\0');
			mkdtemp(&dst_path[0]);
			path.assign(dst_path.begin(), dst_path.end() - 1);

			return path;
		}



	}
}
