/*
** SellaNMS
** $Id: policy_statement.cxx,v 1.8 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.cxx,v 1.8 2006/01/24 07:08:09 sella Exp $";

#include "policy_statement.h"
#include "policy_statement_term.h"

/*
	The default constructor for this class.	
*/
PolicyStatement::PolicyStatement() {
	this->setType("policy-statement");
}

PolicyStatement::PolicyStatement(Statement const &src) {
	/* Utilize operator=(). */
	*this = src;
}

PolicyStatement::PolicyStatement(PolicyStatement const &src) {
	/* Utilize operator=(). */
	*this = src;
}

PolicyStatement::~PolicyStatement() {
}

Statement const& PolicyStatement::operator=(Statement const &src) {
	PolicyStatement *real_src = (PolicyStatement*) &src;

	return operator=(*real_src);
}

PolicyStatement const& PolicyStatement::operator=(PolicyStatement const &src) {
	Statement::operator=(src);

	this->appliedFormatStatement = src.appliedFormatStatement;
	
	return *this;
}


RESULT PolicyStatement::setCompiledStatements(hash_map<string, PolicyStatement> *policies, hash_map<string, MapStatement> *maps) {
	RESULT result = SUCCESS;

	for (slist<Term *>::iterator term = this->terms.begin(); term != this->terms.end(); ++term) {
		if (((PolicyStatementTerm *)(*term))->setCompiledStatements(policies, maps) != SUCCESS) {
			result = FAILURE;
		}	
	}
	return result;
}

/*
	Get a new instance of a policy-statement term.

	Return Values
		A new instance of a policy-statement term (allocated via the new operator).
*/
Term *PolicyStatement::getNewStatementTerm() const {
	return new PolicyStatementTerm();
}

/*
	Get the name of the format-statement applied to this policy-statement.

	Parameters
		format_name:	the name of the format-statement applied to this policy-statement.

	Return Values
		SUCCESS:	if the format-statement name was successfully returned.
		FAILURE: if the format-statement name was not returned.
*/
RESULT PolicyStatement::getAppliedFormatStatement(string &format_name) {
	RESULT result = SUCCESS;

	format_name = this->appliedFormatStatement;
	
	return result;
}

/*
	Get the names of the map-statements applied to this policy-statement.

	Parameters
		map_names:	the names of the map-statements applied to this policy-statement.

	Return Values
		SUCCESS:	if the map-statement names were successfully returned.
		FAILURE: if the map-statement names were not returned.
*/
RESULT PolicyStatement::getAppliedMapStatements(slist<string> &map_names) {
	RESULT result = SUCCESS;

	for (slist<Term *>::iterator t = this->terms.begin(); t != this->terms.end(); ++t) {
		if (((PolicyStatementTerm *)(*t))->getAppliedMapStatements(map_names) != SUCCESS) {
			result = FAILURE;
		}
	}
	map_names.sort();
	map_names.unique();
	
	return result;
}

/*
	Get the names of the variables referenced in the from clauses of the terms in this policy-statement grouped by term.

	Parameters
		referenced:	a list of variable names referenced in the from clause of the terms of this policy-statement grouped by term.

	Return Values
		SUCCESS:	if the referenced variable names were successfully returned.
		FAILURE: if the referenced variable names were not returned.
*/
RESULT PolicyStatement::getReferencedVariables(variable_reference_t &referenced) {
	RESULT result = SUCCESS;

	slist<variable_t>	term_variables;

	for (slist<Term *>::iterator t = this->terms.begin(); t != this->terms.end(); ++t) {
		if (((PolicyStatementTerm *)(*t))->getReferencedVariables(term_variables) != SUCCESS) {
			LMSG("Policy: failed to get referenced variables from term.");

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

/*
	Apply a format-statement to this policy-statement.

	Parameters
		format:	the compiled format-statement to apply to this policy-statement.
	
	Return Values
		SUCCESS:	if the format-statement was successfully applied and this policy-statement ahered to the format.
		FAILURE: if the format-statement failed to apply or this policy-statement did not ahere to the format.
*/
RESULT PolicyStatement::applyFormatStatement(FormatStatement &format) {
	RESULT result = SUCCESS;

	for (slist<Term *>::iterator t = this->terms.begin(); t != this->terms.end(); ++t) {
		if (((PolicyStatementTerm *)(*t))->applyFormatStatement(format) != SUCCESS) {
			result = FAILURE;
		}
	}
	if (result == FAILURE) {
		LMSG("Policy: syntax error in policy-statement %s.", this->getName().c_str());
	}

	return result;
}

/*
	Compile all terms of this policy-statement.

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

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

	if (!config->assignValue("apply-format", this->appliedFormatStatement)) {
		LMSG("Policy: policy-statement missing required 'apply-format' setting.");

		result = FAILURE;
	}
	return result;
}

/*
	Clear all information from this policy-statement.
	
	Return Values
		SUCCESS:	if the policy-statement was successfully cleared.
		FAILURE: if the policy-statement failed to clear.
*/
RESULT PolicyStatement::clear() {
	RESULT result = Statement::clear();
	
	this->appliedFormatStatement.erase();
	
	return result;
}

RESULT PolicyStatement::print(unsigned long depth) {
		return Statement::print(depth);
}

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