/*
 * testResolver.c
 *
 *  Created on: Dec 25, 2010
 *      Author: blackpanther
 */

#include <stdio.h>
#include <stdlib.h>

#include <string.h>

#include "configuration.h"

#include "logger.h"
#include "utilities.h"

#include "result.h"
#include "user.h"
#include "group.h"
#include "problema.h"

#define PROBLEM_FILE         "problem-file"
#define FILLVECTOR           "fill-value"
#define METHOD_PAS_FIXE      "method-pas-fixe"
#define METHOD_PAS_OPTIMAL   "method-pas-optimal"
#define METHOD_NEWTON        "method-newton"
#define METHOD_RECUIT_SIMULE "method-recuit-simule"
#define METHOD_TABOU         "method-tabou"
#define METHOD_GENETIQUE     "method-genetique"

#define PAS               "pas"
#define EPSILON           "epsilon"
#define BORNE_INF         "bounds-min"
#define BORNE_MAX         "bounds-max"
#define PATIENCE          "patience"
#define TEMPERATURE       "temperature"
#define LEVEL_LIMIT       "level-limit"
#define NEIGHBOR_STEP     "neighbor-step"
#define POPULATION_SIZE   "population-size"
#define CROSS_PROBABILITY "cross-probability"
#define MUTA_PROBABILITY  "mutation-probability"

int main(int argc, char** argv) {
	Problema *problem = NULL;
	Result *result = NULL;

	MethodParameters parameters = { 0 };
	double value;
	int intValue;

	xmlConfig_t * config;

	resetToDefaultLogger();
	setLoggerLevel(NONE);

	char *directive;

	int i;

	// Chargement du fichier et initialisation
	config = loadConfiguration("resources/test-Resolver.xml");

	if (!config) {
		logMessage(SEVERE, "configuration file",
				"resources/test-Resolver.xml not found");
		return -1;
	}

	logMessage(INFO, "test suite", "launch");

	//read data from input file
	directive = getProperty(config, PROBLEM_FILE);
	logMessage(DEBUG1,"problem file fetched",directive);
	if (!directive) {
		logMessage(SEVERE, "configuration file", "no problem given");
		return -2;
	}

	problem = (Problema *) parseProblemFromFile(directive);
	free(directive);

	setLoggerLevel(ALL);
	logMessage(DEBUG2,"problem fetched",problem->display(problem));

	if (!problem) {
		logMessage(SEVERE, "configuration file", "error while parsing problem");
		return -3;
	}

	//read data from input file
	directive = getProperty(config, FILLVECTOR);
	logMessage(DEBUG1,"fill value fetched",directive);
	if (!directive) {
		logMessage(SEVERE, "configuration file", "no fill value given");
		return -4;
	}

	double fillvalue = atof(directive);
	free(directive);

	double *vector = (double *) malloc(problem->_dimension * sizeof(double));
	for (i = 0; i < problem->_dimension; i++)
		vector[i] = fillvalue;

	logMessage(DEBUG2,"filled vector",printVector(vector,problem->_dimension));

	//PAS FIXE
	directive = getProperty(config, METHOD_PAS_FIXE);
	logMessage(INFO,"execute gradient pas fixe ?",printBoolean(atoi(directive)));
	if ( atoi(directive) ) {
		free(directive);
		for(i=0;i<MAX_ITEM;i++) {
			free(parameters.parameters[i]);
			parameters.parameters[i] = NULL;
		}
		parameters.data_loaded = 0;

		directive = getProperty(config, PAS);
		logMessage(DEBUG1,"pas fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, STEP_LOADED, &value);

		directive = getProperty(config, EPSILON);
		logMessage(DEBUG1,"epsilon fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, EPSILON_LOADED, &value);

		directive = getProperty(config, PATIENCE);
		logMessage(DEBUG1,"patience fetched",directive);
		intValue = atoi(directive);
		free(directive);

		setParameterProperty(&parameters, PATIENCE_LOADED, &intValue);

		result = resolve(problem, loadMethod(GRADIENT_PAS_FIXE), vector,
				parameters);

		if( result )
			printf("Result pas fixe :%s\n", result->display(result));
		else
			printf("Failed at resolve with gradient pas fixe\n");
	}

	//PAS OPTIMAL
	directive = getProperty(config, METHOD_PAS_OPTIMAL);
	logMessage(INFO,"execute gradient pas optimal ?",printBoolean(atoi(directive)));
	if ( atoi(directive) ) {
		free(directive);
		for(i=0;i<MAX_ITEM;i++) {
			free(parameters.parameters[i]);
			parameters.parameters[i] = NULL;
		}
		parameters.data_loaded = 0;

		directive = getProperty(config, EPSILON);
		logMessage(DEBUG1,"epsilon fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, EPSILON_LOADED, &value);

		directive = getProperty(config, PATIENCE);
		logMessage(DEBUG1,"patience fetched",directive);
		intValue = atoi(directive);
		free(directive);

		setParameterProperty(&parameters, PATIENCE_LOADED, &intValue);

		result = resolve(problem, loadMethod(GRADIENT_PAS_OPTIMAL), vector,
				parameters);

		if( result )
			printf("Result pas optimal :%s\n", result->display(result));
		else
			printf("Failed at resolve with gradient pas optimal\n");
	}

	//NEWTON
	directive = getProperty(config, METHOD_NEWTON);
	logMessage(INFO,"execute newton ?",printBoolean(atoi(directive)));
	if ( atoi(directive) ) {
		free(directive);
		for(i=0;i<MAX_ITEM;i++) {
			free(parameters.parameters[i]);
			parameters.parameters[i] = NULL;
		}
		parameters.data_loaded = 0;

		directive = getProperty(config, EPSILON);
		logMessage(DEBUG1,"epsilon fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, EPSILON_LOADED, &value);

		directive = getProperty(config, PATIENCE);
		logMessage(DEBUG1,"patience fetched",directive);
		intValue = atoi(directive);
		free(directive);

		setParameterProperty(&parameters, PATIENCE_LOADED, &intValue);

		result = resolve(problem, loadMethod(QUASI_NEWTON), vector,
				parameters);

		if( result )
			printf("Result quasi newton :%s\n", result->display(result));
		else
			printf("Failed at resolve with quasi newton\n");
	}

	//RECUIT SIMULE
	directive = getProperty(config, METHOD_RECUIT_SIMULE);
	logMessage(INFO,"execute recuit simule ?",printBoolean(atoi(directive)));
	if ( atoi(directive) ) {
		free(directive);
		for(i=0;i<MAX_ITEM;i++) {
			free(parameters.parameters[i]);
			parameters.parameters[i] = NULL;
		}
		parameters.data_loaded = 0;

		directive = getProperty(config, NEIGHBOR_STEP);
		logMessage(DEBUG1,"neighbor step fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, NEIGHBOR_STEP_LOADED, &value);

		directive = getProperty(config, PATIENCE);
		logMessage(DEBUG1,"patience fetched",directive);
		intValue = atoi(directive);
		free(directive);

		setParameterProperty(&parameters, PATIENCE_LOADED, &intValue);

		directive = getProperty(config, TEMPERATURE);
		logMessage(DEBUG1,"temperature fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, TEMPERATURE_LOADED, &value);

		directive = getProperty(config, LEVEL_LIMIT);
		logMessage(DEBUG1,"level limit fetched",directive);
		intValue = atoi(directive);
		free(directive);

		setParameterProperty(&parameters, LEVEL_LIMIT_LOADED, &intValue);

		result = resolve(problem, loadMethod(RECUIT_SIMULE), vector,
				parameters);

		if( result )
			printf("Result simulated annealing :%s\n", result->display(result));
		else
			printf("Failed at resolve with simulated annealing\n");
	}

	//TABOU
	directive = getProperty(config, METHOD_TABOU);
	logMessage(INFO,"execute tabou ?",printBoolean(atoi(directive)));
	if ( atoi(directive) ) {
		free(directive);
		for(i=0;i<MAX_ITEM;i++) {
			free(parameters.parameters[i]);
			parameters.parameters[i] = NULL;
		}
		parameters.data_loaded = 0;

		directive = getProperty(config, PATIENCE);
		logMessage(DEBUG1,"patience fetched",directive);
		intValue = atoi(directive);
		free(directive);

		setParameterProperty(&parameters, PATIENCE_LOADED, &intValue);

		directive = getProperty(config, NEIGHBOR_STEP);
		logMessage(DEBUG1,"neighbor step fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, NEIGHBOR_STEP_LOADED, &value);

		result = resolve(problem, loadMethod(RECHERCHE_TABOU), vector,
				parameters);

		if( result )
			printf("Result tabou :%s\n", result->display(result));
		else
			printf("Failed at resolve with tabou\n");
	}

	//GENETIC
	directive = getProperty(config, METHOD_GENETIQUE);
	logMessage(INFO,"execute genetique ?",printBoolean(atoi(directive)));
	if ( atoi(directive) ) {
		free(directive);
		for(i=0;i<MAX_ITEM;i++) {
			free(parameters.parameters[i]);
			parameters.parameters[i] = NULL;
		}
		parameters.data_loaded = 0;

		directive = getProperty(config, POPULATION_SIZE);
		logMessage(DEBUG1,"population size fetched",directive);
		intValue = atoi(directive);
		free(directive);

		setParameterProperty(&parameters, POPULATION_SIZE_LOADED, &intValue);

		directive = getProperty(config, PATIENCE);
		logMessage(DEBUG1,"patience fetched",directive);
		intValue = atoi(directive);
		free(directive);

		setParameterProperty(&parameters, PATIENCE_LOADED, &intValue);

		directive = getProperty(config, CROSS_PROBABILITY);
		logMessage(DEBUG1,"cross probability fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, CROSS_PROBA_LOADED, &value);

		directive = getProperty(config, MUTA_PROBABILITY);
		logMessage(DEBUG1,"mutation probability fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, MUTATION_PROBA_LOADED, &value);

		directive = getProperty(config, BORNE_INF);
		logMessage(DEBUG1,"bounds min fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, BOUNDS_MIN_LOADED, &value);

		directive = getProperty(config, BORNE_MAX);
		logMessage(DEBUG1,"bounds max fetched",directive);
		value = atof(directive);
		free(directive);

		setParameterProperty(&parameters, BOUNDS_MAX_LOADED, &value);

		result = resolve(problem, loadMethod(ALGORITHME_GENETIQUE), vector,
				parameters);

		if( result )
			printf("Result genetic algorithm :%s\n", result->display(result));
		else
			printf("Failed at resolve with genetic algorithm\n");
	}

	logMessage(DEBUG1, "destroy", "config");
	destroyConfig(config);

	logMessage(INFO, "exiting", "");
	return (EXIT_SUCCESS);
}

