/*
    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 "arch_headers.h"
#include "Options.h"

// corpus file
#define CFG_CORPUS "corpus"
// corpus info
#define CFG_CORPUS_INFO "corpus-info"
// dictionary file
#define CFG_DICT_FILE "words-dict"
// workdir
#define CFG_WORKDIR "workdir" 
// matrix name
#define CFG_MATRIX_NAME "matrix-name"
// column_operators multiword
#define CFG_COLUMNS_ME "column-me"
// column operators simple words
#define CFG_COLUMNS_SIMPLE "column-simple"
// jw wiersza
#define CFG_ROW_ME "row-me"
// slowa wiersza
#define CFG_ROW_SIMPLE_WORDS "row-simple-words"
// czy filtrowac disamby
#define CFG_FILTER_DISAMB "filter-disamb"
//Ile operatorow na kazdym procesie
#define CFG_OPERATORS_PER_NODE "operators-per-node"

#define CFG_HELP "help"
#define CFG_CONFIG_FILE "cfg-file"

#define CFG_DICT_ONLY "dict-only"
#define CFG_DICT_FLEX "flex"
#define CFG_DICT_MASS "mass-limit"
#define CFG_DICT_TF "min-tf"
#define CFG_DICT_STOPLIST "stoplist"
#define CFG_DICT_CHAR_STOPLIST "char-stoplist"
#define CFG_TEMP_DICT_DIR "temp-dir"
#define CFG_FAVOR_GERS "favor-gers"

// poliqarp query size
#define CFG_QUERY_SIZE "pq-size"

#define CFG_REMOVE_AMB_INTERP "remove-ambiguous-interpretation"


namespace me_architect
{
	Options::Options(int argc, char *argv[], Config *config)
		: m_pConfig(config)
	{
		Initalize(argc, argv);
	}

	void Options::Initalize(int argc, char *argv[])
	{
		namespace po= boost::program_options;
		std::string configfile, corpus_type_str, filter_disamb_str;
		std::vector<std::string> flexes;
		
		po::options_description cmdline("Command line only options", 100);
		po::options_description basic("Basic options", 100);

		cmdline.add_options()
				(CFG_HELP, "Prints this message")
				(CFG_CONFIG_FILE, po::value<std::string>(&configfile)->default_value(std::string("me_architect.cfg")), "Config file")
				(CFG_DICT_ONLY,"Whether application should only make dictionary")
				;
		basic.add_options()
				(CFG_CORPUS, po::value<std::vector<std::string> >(& m_pConfig->m_sCorpusFiles), "Poliqarp corpus path ")
				(CFG_DICT_FILE, po::value<std::string>(& m_pConfig->dictWithWords), "Dictionary with words and their flex classes. With --dict-only - target file")
				(CFG_CORPUS_INFO, po::value<std::string>(& m_pConfig->m_sCorpusInfo), "Corpus description")
				(CFG_WORKDIR, po::value<std::string>(& m_pConfig->m_sWorkdir), "Workdir (output dir for matrix)")
				(CFG_MATRIX_NAME, po::value<std::string>(& m_pConfig->m_sMatrixName), "Matrix name" )
				(CFG_ROW_SIMPLE_WORDS, po::value<std::vector<std::string> >(& m_pConfig->m_vRowTermFiles ), "Single word lexical units for rows, format:\n"
				 "file_with_units|flex_class")
				(CFG_ROW_ME, po::value<std::vector<std::string> >(& m_pConfig->m_vRowUnits), "Files with multiwords expresions for rows")
				(CFG_COLUMNS_ME, po::value<std::vector<std::string> >(& m_pConfig->m_vOperatorsME), "Column description, format:\n"
				 "file_with_joskipi_operator|file_with_mulitowrds_expresions")
				(CFG_COLUMNS_SIMPLE, po::value<std::vector<std::string> >(& m_pConfig->m_vOperatorsSimple), "Column description, format:\n"
				 "file_with_joskipi_operator|file_with_words|flex_class")
				(CFG_FILTER_DISAMB, po::value<std::string>(&filter_disamb_str)->default_value("true"), "If true only non-disambs will be filtered out")
				(CFG_OPERATORS_PER_NODE, po::value<int>(&m_pConfig->operatorsPerNode)->default_value(-1), "Number of operators computed at once at each node")
				(CFG_DICT_FLEX, po::value<std::vector<std::string> >(&flexes),"Flexes for dictionary")
				(CFG_DICT_TF, po::value<size_t>(&m_pConfig->min_tf)->default_value(5), "Minimal tf to consider word for dictionary")
				(CFG_DICT_STOPLIST, po::value<std::vector<std::string> >(&m_pConfig->stoplistFiles), "Files with word ommited in dictionary")
				(CFG_DICT_CHAR_STOPLIST, po::value<std::vector<std::string> >(&m_pConfig->charStoplistFiles), "Files with chars making whole word ommited in dictionary")
				(CFG_QUERY_SIZE, po::value<size_t>(&m_pConfig->query_size)->default_value(10000), "Size of maximum sentence to process")
				(CFG_TEMP_DICT_DIR, po::value<std::string>(&m_pConfig->tempDictDir), "Directory for temporary dictionaries")
				(CFG_REMOVE_AMB_INTERP, po::value<bool>(&m_pConfig->removeAmbInterp)->default_value(false), "Remove ambiguouos interpretations from dict")
				(CFG_FAVOR_GERS, po::value<bool>(&m_pConfig->favorGers)->default_value(false), "Favor gers to substs in ambiguous flexes")
				;

		po::variables_map vm;
		po::options_description all("",100);
		
		all.add(cmdline).add(basic);

		po::store(po::parse_command_line(argc, argv, all), vm);
		po::notify(vm); 

		if( vm.count(CFG_HELP) )
		{
			std::cout << "ME_ARCHITECT, by Bartosz Broda, bartosz.broda@pwr.wroc.pl\n";
			std::cout << all << std::endl;
			exit(0);
		}
		std::ifstream cfgfile( configfile.c_str() );

		if(cfgfile)
		{
			po::store(po::parse_config_file(cfgfile, basic), vm);
			po::notify(vm);
		}
		else if( vm.count(CFG_CONFIG_FILE) )
			std::cerr << "Cannot open config file " << configfile << ". Proceeding with defaults...\n";

		boost::to_lower	(filter_disamb_str);
		if( filter_disamb_str == "true" )
			m_pConfig->m_bFilterDisamb = true;
		else
			m_pConfig->m_bFilterDisamb = false;
		if(vm.count("dict-only"))
			m_pConfig->dictOnly=true;
		else
			m_pConfig->dictOnly=false;
		if(m_pConfig->dictOnly)
		{
			for(int i=0;i<(int)flexes.size();i++)
			{
				m_pConfig->flexes.insert(Corpus::CTag::GetFlexClass(flexes[i]));
			}
		}
		if(!vm.count(CFG_TEMP_DICT_DIR))
			m_pConfig->tempDictDir = m_pConfig->m_sWorkdir;
	}
}

