#include "config.h"
#include "storage.h"
#include <string>

#include <dynamic.h>

#ifdef HAVE_CONFIG_H
#include <conf_config.h>
#endif

#ifdef Revision
#undef Revision
#endif
#define Revision "config.cpp $Revision: 1.1.1.1 $"

static Storage<std::string, Config_Interface*> _configs;
static std::string last_error;

bool config_create ( std::string name, std::string driver, std::string * params, int params_num, bool replace )
{
	if ( _configs.exist ( name ) )
	{
		if ( replace )
		{
			Config_Interface *z;
			z=_configs.get ( name );
			delete z;
			_configs.remove ( name );
		}
		else
		{
			last_error = name + " already exist";
			return false;
		}
	}
	if ( !module_load ( driver ) )
	{
		last_error = dynamic_error();
		return false;
	}

	Dynamic_Module *mod;
	if ( ( mod = module_get ( driver ) ) == 0 )
	{
		last_error =  dynamic_error();
		return false;
	}
	if ( !mod->_symbol_load ( "_get_config_interface" ) )
	{
		module_remove ( driver );
		last_error = dynamic_error();
		return false;
	}
	Config_Interface* ( *fun ) ( std::string * params, int params_num );
	if ( ( fun = ( Config_Interface * ( * ) ( std::string *, int ) ) ( *mod ) [ "_get_config_interface" ] ) == 0 )
	{
		module_remove ( driver );
		mod->_symbol_remove ( "_get_config_interface" );
		last_error = dynamic_error();
		return false;
	}
	Config_Interface *intf;
	intf=fun ( params,params_num );
	last_error="";
	return _configs.insert ( name, intf );
}

bool config_remove ( std::string name )
{
	last_error="";
	if ( !_configs.exist ( name ) ) return true;
	Config_Interface *z;
	z=_configs.get ( name );

	Dynamic_Module *mod;
	if ( ( mod = module_get ( z->_get_driver_name() ) ) == 0 )
	{
		last_error = dynamic_error();
	}
	else mod->_symbol_remove ( "_get_config_interface" );
	module_remove ( z->_get_driver_name() );
	return _configs.remove ( name );

}
Config_Interface * config_get_interface ( std::string name )
{
	if ( _configs.exist ( name ) ) return _configs.get ( name );
	else return 0;
}

std::string config_error( )
{
	return last_error;
}
std::string config_version()
{
	return VERSION;
}

std::string config_get_value ( std::string conf, std::string name, std::string def )
{

	Config_Interface *cfg=config_get_interface ( conf );
	if ( cfg==0 ) return def;
	return cfg->_get_value ( name,def );
}

bool config_set_value ( std::string conf, std::string name, std::string val, bool replace )
{
	Config_Interface *cfg=config_get_interface ( conf );
	if ( !cfg ) return false;
	return cfg->_set_value ( name,val,replace );
}



