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








Options::Options(int ac, char *av[])
{
	InitOptions(ac,av);
}

Params& Options::GetParams()
{
	return m_Params;
}
void Options::CheckMatrices()
{
	if( m_vMatrices.size() < 2 )
		throw std::runtime_error("Specify at least two matrices to join...");
	for(size_t matrix_no = 0; matrix_no < m_vMatrices.size(); matrix_no++)
	{
		std::string matrix_full_path = m_vMatrices[matrix_no];

		boost::filesystem::path p(matrix_full_path);
		p.normalize();
		std::string matrix_name = p.filename().c_str();
		std::string matrix_dir = p.branch_path().string();
		Matrices::IO::CheckSuperMatrixFiles(matrix_dir, matrix_name);
		m_Params.m_vMatrixNameToPath.push_back( std::pair<std::string, std::string>( matrix_name, matrix_dir) );
	}
}

void Options::InitOptions(int ac, char *av[])
	{
		namespace po = boost::program_options;

		po::options_description cmdline("Command line only options", 100);
		po::options_description basic("Basic options", 100);
		std::string configfile;
		m_Params.appendTF = false;

		cmdline.add_options()
			("help", "Prints this message")
			("cfg-file", po::value<std::string>(&configfile), "Config file")
			;
		basic.add_options()
			("matrix", po::value<std::vector<std::string> >(&m_vMatrices), "Matrix to join (specify two or more)")
			("out-dir", po::value<std::string>( & m_Params.m_sOutputDir ), "Output directory for joined matrix")
			("out-name", po::value<std::string>( & m_Params.m_sMatrixOutName ), "Name of joined matrix ")


			("corpus-info", po::value<std::string>( & m_Params.m_sCorpusInfo ), "Corpus info (for all matrices)")
			("unit-count", po::value<size_t>( & m_Params.m_stUnitCount ), "Number of lexical units in corpora")
			("append-TF", po::value<bool>( & m_Params.appendTF ), "Whether to sum TFs or append")


			;

		po::options_description all("",100);
		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 << "Matrix Summator by Bartosz Broda, bartosz.broda@pwr.wroc.pl\n" << 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 defaults...\n";




		if(! vm.count("unit-count") )
			throw std::runtime_error("unit-count should be set!");
		if(! vm.count("corpus-info") )
			throw std::runtime_error("corpus-info should be set!");
		if(! vm.count("out-name") )
			throw std::runtime_error("out-name should be set!");

		CheckMatrices();
		CheckOutDir();
	}
	void Options::CheckOutDir()
	{

		boost::filesystem::path p(m_Params.m_sOutputDir);
		if( boost::filesystem::exists(p))
		{
			if(!boost::filesystem::is_directory(p) )
				throw std::runtime_error("Output path exists, but is not a directory: " + m_Params.m_sOutputDir );
		}
		else
		{
			boost::filesystem::create_directory(p);
			if( !boost::filesystem::exists(p))
				throw std::runtime_error("Cannot create output directory: " + m_Params.m_sOutputDir);
		}

	}
