/*
** SellaNMS
** $Id: policy_statement_from.cxx,v 1.11 2006/01/24 07:08:09 sella Exp $
** Copyright (c) 2001-2005 Digital Genesis Software, LLC. All Rights Reserved.
** Released under the GPL Version 2 License.
** http://www.digitalgenesis.com
*/

static const char rcsid[] = "$Id: policy_statement_from.cxx,v 1.11 2006/01/24 07:08:09 sella Exp $";

#include "policy_statement_from.h"
#include "policy_statement_from_variable.h"
#include "common/snmp_util.h"

#include <sys/timeb.h>
#include <stdio.h>
#include <stl/vector>
#include <stl/string>

PolicyStatementFrom::PolicyStatementFrom() {
}

PolicyStatementFrom::PolicyStatementFrom(From const &src) {
	*this = src;
}

PolicyStatementFrom::PolicyStatementFrom(PolicyStatementFrom const &src) {
	*this = src;
}

PolicyStatementFrom::~PolicyStatementFrom() {

}

From const& PolicyStatementFrom::operator=(From const &src) {
	/* Typecast src to its real type. */
	PolicyStatementFrom *real_src = (PolicyStatementFrom*) &src;

	return operator=(*real_src);
}

PolicyStatementFrom const& PolicyStatementFrom::operator=(PolicyStatementFrom const &src) {
	/* Wipe contents. */
	this->clear();

	/* Do object specifics. */
	this->variables = src.variables;

	return *this;
}

RESULT PolicyStatementFrom::getAppliedMapStatements(slist<string> &map_names) {
	RESULT result = SUCCESS;

	for (slist<PolicyStatementFromVariable>::iterator v = this->variables.begin(); v != this->variables.end(); ++v) {
		if (v->getAppliedMapStatements(map_names) != SUCCESS) {
			LMSG("Policy: failed to get applied map-statements.");

			result = FAILURE;
		}
	}
	return result;
}

RESULT PolicyStatementFrom::getReferencedVariables(slist<variable_t> &referenced) {
	RESULT result = SUCCESS;

	variable_t	variable;

	for (slist<PolicyStatementFromVariable>::iterator v = this->variables.begin(); v != this->variables.end(); ++v) {
		if (v->getReferencedVariable(variable) != SUCCESS) {
			LMSG("Policy: failed to get referenced variable.");

			result = FAILURE;
		} else {
			if (!variable.values.empty()) {
				referenced.insert(referenced.end(), variable);
			}
		}
	}
	return result;
}

RESULT PolicyStatementFrom::setCompiledStatements(hash_map<string, PolicyStatement> *policies, hash_map<string, MapStatement> *maps) {
	for (slist<PolicyStatementFromVariable>::iterator v = this->variables.begin(); v != this->variables.end(); ++v) {
		v->setCompiledStatements(policies, maps);
	}

	return SUCCESS;
}

ACTION PolicyStatementFrom::evaluate(variable_binding_t &input) {
	for (slist<PolicyStatementFromVariable>::iterator v = this->variables.begin(); v != this->variables.end(); ++v) {
		if (v->evaluate(input) != ACTION_THEN) {
			return ACTION_NEXT_TERM;
		}
	}
	return ACTION_THEN;
}

/*
	Compile all information in this from clause.

	Parameters
		config:	the section of the configuration from the level "policy-options <statement-type> <statement-name> term <term-name> from"

	Return Values
		SUCCESS:	if the policy-statement from clause was successfully compiled.
		FAILURE: if the policy-statement from clause failed to compile.
*/
RESULT PolicyStatementFrom::compile(ConfigNode *config) {
	RESULT result = SUCCESS;

	ConfigNode							variable_config;
	vector<string>						variable_names;

	string								oid;

	PolicyStatementFromVariable	variable;

	if (config->assignValues("", variable_names)) {
		for (vector<string>::iterator name = variable_names.begin(); name != variable_names.end(); ++name) {
			variable.clear();

			oid = *name;
			resolveMIBObject(oid);
			variable.setName(oid);

			variable.setStorage(this->storage);

			if (config->assignNode(*name, variable_config)) {
				if (variable.compile(&variable_config) == SUCCESS) {
					this->variables.insert(this->variables.end(), variable);
				} else {
					result = FAILURE;
				}
			} else {
				result = FAILURE;
			}
		}
	}
	return result;
}

RESULT PolicyStatementFrom::applyFormatStatement(FormatStatement &format) {
	RESULT result = SUCCESS;

	for (slist<PolicyStatementFromVariable>::iterator v = this->variables.begin(); v != this->variables.end(); ++v) {
		if (v->applyFormatStatement(format) != SUCCESS) {
			result = FAILURE;
		}
	}
	return result;
}

/*
	Print all information from this from clause.
	
	Return Values
		SUCCESS:	if the from clause was successfully printed.
		FAILURE: if the from clause failed to print.
*/
RESULT PolicyStatementFrom::print(unsigned long depth) {
	string	tab = "";
	for (unsigned long i = 0; i < depth; i++) {
		tab.append("   ");
	}

	LMSG("%sfrom {", tab.c_str());

	for (slist<PolicyStatementFromVariable>::iterator v = this->variables.begin(); v != this->variables.end(); ++v) {
		v->print(depth + 1);
	}
	
	LMSG("%s}", tab.c_str());

	return SUCCESS;
}
  
/*
	Clear all information from this from clause.
	
	Return Values
		SUCCESS:	if the from clause was successfully cleared.
		FAILURE: if the from clause failed to clear.
*/
RESULT PolicyStatementFrom::clear() {
	this->variables.clear();

	return SUCCESS;
}

/*
** Local Variables:
** c-basic-offset: 3
** tab-width: 3
** End:
** vim:
** vim: noet ts=3 sw=3 sts=3
*/
