/*
    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 "Config.h"

namespace doc_term_architect
{
	Config* Config::m_pInstance = NULL;

	Config* Config::Initalize(int argc, char* argv[])
	{
		if(m_pInstance)
			Delete();
		//TODO parse program options

		
		m_pInstance = new Config();
		m_pInstance->m_iThreads = 1;
		m_pInstance->m_sWorkDir = "/mnt/data/workdir/macierze/supermatrix2/doc/";
		m_pInstance->m_sMatrixName = "knigi_beta_doc_term";
		m_pInstance->m_sCorpusInfo = "KNIGI - 12 V 2008 / tagged with guesser";
		m_pInstance->m_sTermsFilename = "/home/boban/knigi_words_mintf10.out";
		m_pInstance->m_sDocumentFilename = "/home/boban/data2/korpusy/KNIGI/morphs_guesser.txt";
		m_pInstance->m_sDictionary = "/mnt/data/workdir/macierze/supermatrix2/doc/dict_dzp98_kipi.txt";
	
		m_pInstance->LoadTerms();
		m_pInstance->LoadDocuments();

		if(m_pInstance->m_iThreads > 1 )
		{
			std::cout << "When there is more then one thread, we need full dictionary...\n";
			Corpus::CWordDictionary *dict = Corpus::CWordDictionary::GetInstance();
			std::ifstream file(m_pInstance->m_sDictionary.c_str() );
			if(!file)
				throw std::runtime_error("Cannot open dictionary  for reading: " + m_pInstance->m_sDictionary);
			dict->DeserializeFromText(file);
			file.close();
		}
		return m_pInstance;
	}

	Config* Config::GetInstance()
	{
		return m_pInstance;
	}

	void Config::Delete()
	{
		if(m_pInstance)
		{
			delete m_pInstance;
			m_pInstance = NULL;
		}
	}

	void Config::LoadTerms()
	{
		m_vColumnTerms.clear();
		LoadList(m_sTermsFilename, m_vColumnTerms);
		BuildTermsIndex();
	}

	void Config::LoadDocuments()
	{
		m_vDocumentList.clear();
		LoadList( m_sDocumentFilename, m_vDocumentList);
	}

	void Config::BuildTermsIndex()
	{
		Corpus::CWordDictionary *dict = Corpus::CWordDictionary::GetInstance();
		for(size_t term_no = 0; term_no < m_vColumnTerms.size(); term_no++)
		{
			std::vector<std::string> tokens;
			boost::split( tokens, m_vColumnTerms[term_no], boost::is_any_of(":") );
			if( tokens.size() != 3 )
				throw std::runtime_error( "Wrong format of terms file... Term: " + m_vColumnTerms[term_no] );
			//flex [0], term[1]
			std::string flex_str = tokens[0];
			boost::trim(flex_str);
			Corpus::TFlexClass flex = Corpus::CTag::GetFlexClass( flex_str);
			std::map<int, size_t> &inner_index = m_mTermIndex[flex];
			std::string word = tokens[1];
			boost::trim(word);
			int word_index = dict->Add( word );
			if( inner_index.find(word_index) != inner_index.end() )//ups!
				throw std::runtime_error( "Multiple words with the same base in one flex class: " + m_vColumnTerms[term_no] );

			inner_index[ word_index ] = term_no;
		}
	}

	void Config::LoadList(const std::string &filename, std::vector<std::string> &lines)
	{
		std::ifstream file( filename.c_str() );
		if( !file )
			throw std::runtime_error( "Cannot open file: " + filename );

		std::string line;
		while( std::getline(file, line) )
		{
			boost::trim(line);
			if( line.length() > 0 )
				lines.push_back(line);
		}

	}
}//namespace doc_term_architect
