/*
    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"
#define CFG_HELP "help"
#define CFG_CONFIG_FILE "cfg-file"
#define CFG_WBST_TESTER "wbst-tester"
#define CFG_NODES "nodes"
#define CFG_HOSTFILE "hostfile-path"
#define CFG_SEED "seed"
#define CFG_NUM_OF_FOLDS "folds-num"
#define CFG_WORKDIR "workdir"
#define CFG_WBST "wbst-test"
#define CFG_FUNCTION "function-file"
#define CFG_MATRIX_PATH "matrix-path"
#define CFG_FLEX "flex"
#define CFG_LOAD_CCS "load-ccs"
#define CFG_PAR_POP_SIZE "parents-population-size"
#define CFG_CHILD_POP_SIZE "children-population-size"
#define CFG_ITERATIONS "iterations"


Config* Config::instance=NULL;



void Config::init(int ac,char**av)
{
	if(instance==NULL)
		instance = new Config();
	instance->initOptions(ac,av);
}

Config* Config::getInstance()
{

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

void Config::initOptions(int ac,char**av)
{
	namespace po= boost::program_options;
	std::string configfile;

	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), "Config file")

			;
	basic.add_options()
			(CFG_WBST_TESTER, po::value<std::string>(& wbstTesterPath), "Path for WBST tester")
			(CFG_NODES, po::value<int>(& numOfNodes)->default_value(2), "Number of nodes available for computation")
			(CFG_HOSTFILE, po::value<std::string>(& hostFile), "Hostfile for mpirun")
			(CFG_SEED, po::value<int>(& randomSeed), "Seed for randomize function")
			(CFG_NUM_OF_FOLDS, po::value<int>(& numOfFolds), "Number of folds" )
			(CFG_WORKDIR, po::value<std::string> (& workdir), "Path for temporary files")
			(CFG_WBST, po::value<std::string>(& wbstTestFile), "File with WBST tests for learning")
			(CFG_MATRIX_PATH, po::value<std::string>(& matrix), "Path with matrix")
			(CFG_FLEX, po::value<std::string>(& flex)->default_value("subst"),"Flex class for wbst files")
			(CFG_LOAD_CCS, "Whether matrices should be load using ccs file or not")
			(CFG_FUNCTION, po::value<std::string> (& functionFile), "File with function to be parsed")
			(CFG_PAR_POP_SIZE, po::value<int> (& parentsPopulationSize), "Size of parents' population for genetic algorithm")
			(CFG_CHILD_POP_SIZE, po::value<int> (& childrenPopulationSize), "Size of children population for genetic algorithm")
			(CFG_ITERATIONS, po::value<int> (&iterations), "Number of iterations for genetic algorithm")

			;

	po::variables_map vm;
	po::options_description all("",100);

	all.add(cmdline).add(basic);

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

	if( vm.count(CFG_HELP) )
	{
		std::cout << "WBST function optimizer, by Damian Jaworski, 150019@student.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) )
		throw std::runtime_error("Cannot open config file\n");
	if(vm.count(CFG_LOAD_CCS))
		loadCCS=true;
	else
		loadCCS=false;


}
