//----------------------------------------------------------------------------
//
//  Copyright (C) Red Hat, Inc., 2015.
//
//  File:       WsmanFilter.cpp
//
//  License:    BSD-3-Clause
//
//  Contents:   A C++ interface for filter_t
//
//----------------------------------------------------------------------------

#include <cstdlib>
#include "WsmanEPR.h"
#include "WsmanFilter.h"

using namespace WsmanClientNamespace;

WsmanFilter::WsmanFilter(const WsmanFilter &filter)
	: filter(filter_copy(filter.getFilter()))
{
}

WsmanFilter::WsmanFilter(const string &dialect, const string &query)
	: filter(filter_create_simple(dialect.c_str(), query.c_str()))
{
}

WsmanFilter::WsmanFilter(const NameValuePairs *s)
	: filter(NULL)
{
	addSelectors(s);
}

WsmanFilter::WsmanFilter(
	const WsmanEPR &epr,
	enum WsmanAssocType assocType,
	const string &assocClass,
	const string &resultClass,
	const string &role,
	const string &resultRole,
	const vector<string> &resultProp)
{
	int i = 0;
	char **props = NULL;

	if (!resultProp.empty()) {
		props = static_cast<char**>(malloc(sizeof(char *) * resultProp.size()));
		vector<string>::const_iterator itr;
		for (itr = resultProp.begin(); itr != resultProp.end(); itr++, i++) {
			props[i] = const_cast<char*>(itr->c_str());
		}
	}

	filter = filter_create_assoc(
		epr,
		static_cast<int>(assocType),
		(assocClass.empty() ? NULL : assocClass.c_str()),
		(resultClass.empty()? NULL : resultClass.c_str()),
		(role.empty() ? NULL : role.c_str()),
		(resultRole.empty() ? NULL : resultRole.c_str()),
		props, i);

	free(props);
}

WsmanFilter::~WsmanFilter()
{
	if (filter) {
		filter_destroy(filter);
		filter = NULL;
	}
}

filter_t *WsmanFilter::makeFilterSelector()
{
	if (!filter)
		filter = filter_create_selector(NULL);
	return filter;
}

int WsmanFilter::addSelector(const char *key, const char *value)
{
	return filter_add_selector(makeFilterSelector(), key, value);
}

int WsmanFilter::addSelector(const string &name, const string &value)
{
	return addSelector(name.c_str(), value.c_str());
}

void WsmanFilter::addSelectors(const NameValuePairs &selectors)
{
	NameValuePairs::const_iterator it;
	for (it = selectors.begin(); it != selectors.end(); ++it)
		addSelector(it->first, it->second);
}

void WsmanFilter::addSelectors(const NameValuePairs *selectors)
{
	if (!selectors)
		return;

	addSelectors(*selectors);
}

filter_t *WsmanFilter::getFilter() const
{
	return filter;
}

WsmanFilter::operator filter_t*() const
{
	return getFilter();
}
