/*
    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"
#include <boost/program_options.hpp>
#include <iostream>
#include <fstream>
#include <sstream>

#include <boost/algorithm/string.hpp>

#include <boost/foreach.hpp>

namespace windowbuilder{

	void config::load_wordlist(const std::string &filename, std::set<std::string> &where)
	{
		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::algorithm::trim(line);
			where.insert(line);
		}

	}

	config config::parse_args(int ac, char **av)
	{
		namespace po = boost::program_options;

		std::vector<std::string> row_poses_vec, column_poses_vec;
		std::string row_words_file, column_words_file;

		config cfg;

		po::options_description cmdline("Command line only options", 100);
		po::options_description basic("Basic options", 100);
		std::string configfile, opstr;

		cmdline.add_options()
			("help", "Prints this message")
			("cfg-file", po::value<std::string>(&configfile)->default_value(std::string("builder.cfg")),
				"Optional config file")
			;
		basic.add_options()
			("tagset,t", po::value<std::string>(&cfg.tagset)->default_value("kipi"),
				"Name of a tagset")
			("reader,r", po::value<std::string>(&cfg.reader_class), "Name of a reader")
			("corpus,c", po::value<std::vector<std::string> >(&cfg.corpora), "Path(s) to corpus")
			("outfile,o", po::value<std::string>(&cfg.outfile)->default_value("out.csv"),
				"Path for file with results")
			("dump-interval,d", po::value<size_t>(&cfg.dump_interval)->default_value(100000),
				"Dump interval (in sentences)")
			("row-poses", po::value<std::vector<std::string> >(&row_poses_vec),
				"Row POSes. If not set then all poses will be used.")
			("column-poses", po::value<std::vector<std::string> >(&column_poses_vec),
				"Column POSes. If not set then all poses will be used.")
			("row-words-file", po::value<std::string>(&row_words_file), "File with words for row. "
				"Every line consists of pos:baseform. If not set then all words will be used "
				"(after POS filtering)")
			("column-words-file", po::value<std::string>(&column_words_file), "File with words for columns. "
				"Every line consists of pos:baseform. If not set then all words will be used "
				"(after POS filtering)")
			("simple", po::value<bool>(&cfg.simple)->default_value(false),
			 "If set to true, no order of word information will be retained.")
			("max_window", po::value<long>(&cfg.max_window)->default_value(100000),
			 "Max window size.")
			;

		po::options_description all("",80);
		all.add(cmdline).add(basic);

		po::variables_map vm;
		po::store(po::parse_command_line(ac, av, all), vm);
		po::notify(vm);

		if( vm.count("help" ) )
		{
			std::cout << "Builder by Bartosz Broda, bartosz.broda@gmail.com\n";
			std::cout << "Extracts tuples for building window matrices from Polish corpora\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-file") )
			std::cerr << "Cannot open config file " << configfile << ". Proceeding with commandline and defaults...\n";

		if(! vm.count("reader"))
		{
			std::cerr << "You need to specify reader" <<  std::endl;
			exit(1);
		}
		if(! vm.count("corpus"))
		{
			std::cerr << "You need to specify at least one corpus" <<  std::endl;
			exit(1);
		}

		std::copy(row_poses_vec.begin(), row_poses_vec.end(),
				  std::inserter(cfg.row_poses, cfg.row_poses.end()));
		std::copy(column_poses_vec.begin(), column_poses_vec.end(),
				  std::inserter(cfg.column_poses, cfg.column_poses.end()));

		if(vm.count("row-words-file"))
			load_wordlist(row_words_file, cfg.row_wordpos);
		if(vm.count("column-words-file"))
			load_wordlist(column_words_file, cfg.column_wordpos);

		return cfg;
	}
}//namespace builder
