// $Id: Rule.cc,v 1.4 2003/08/31 00:38:11 vern Exp $

#include "config.h"

#include "Rule.h"
#include "RuleMatcher.h"

// Start at one as we want search for this within a list,
// and List's is_member returns zero for non-membership ...
unsigned int Rule::rule_counter = 1;
unsigned int Rule::pattern_counter = 0;
rule_list Rule::rule_table;

Rule::~Rule()
	{
	delete [] id;

	loop_over_list(patterns, i)
		{
		delete [] patterns[i]->pattern;
		delete patterns[i];
		}

	loop_over_list(hdr_tests, j)
		delete hdr_tests[j];

	loop_over_list(conditions, k)
		delete conditions[k];

	loop_over_list(actions, l)
		delete actions[l];

	loop_over_list(preconds, m)
		{
		delete [] preconds[m]->id;
		delete preconds[m];
		}
	}

const char* Rule::TypeToString(Rule::PatternType type)
	{
	static const char* labels[] = { "Payload", "HTTP", "FTP", "Finger" };
	return labels[type];
	}

void Rule::PrintDebug()
	{
	fprintf(stderr, "Rule %s (%d)\n", id, idx);

	loop_over_list(patterns, i)
		{
		fprintf(stderr, "	%-8s |%s| (%d) \n",
			TypeToString(patterns[i]->type), patterns[i]->pattern,
			patterns[i]->id);
		}

	loop_over_list(hdr_tests, j)
		hdr_tests[j]->PrintDebug();

	loop_over_list(conditions, k)
		conditions[k]->PrintDebug();

	loop_over_list(actions, l)
		actions[l]->PrintDebug();

	fputs("\n", stderr);
	}

void Rule::AddPattern(const char* str, Rule::PatternType type,
			uint32 offset, uint32 depth)
	{
	Pattern* p = new Pattern;
	p->pattern = copy_string(str);
	p->type = type;
	p->id = ++pattern_counter;
	p->offset = offset;
	p->depth = depth;
	patterns.append(p);

	rule_table.append(this);
	}

void Rule::AddRequires(const char* id, bool opposite_direction, bool negate)
	{
	Precond* p = new Precond;
	p->id = copy_string(id);
	p->rule = 0;
	p->opposite_dir = opposite_direction;
	p->negate = negate;

	preconds.append(p);
	}

void Rule::SortHdrTests()
	{
	// FIXME: Do nothing for now - we may want to come up with
	// something clever here.
	}
