/*******************************************************************************
 * Copyright (C) 2004-2006 Intel Corp. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 *  - Neither the name of Intel Corp. nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/

/**
 * @author Liang Hou, Intel Corp.
 */

#include "u/libu.h"
#include "wsman-xml.h"
#include "wsman-names.h"
#include "wsman-filter.h"

filter_t * filter_initialize(void)
{
	filter_t *filter = u_zalloc(sizeof(filter_t));
	return filter;
}


static int filter_set(filter_t *filter, const char *dialect, const char *query, epr_t *epr, hash_t *selectors,
	const int assocType, const char *assocClass, const char *resultClass, const char *role,
	const char *resultRole, char **resultProp, const int propNum)
{
	int i = 0;

	if(dialect == NULL) {
		filter->dialect = u_strdup(WSM_XPATH_FILTER_DIALECT);
	} else {
		filter->dialect = u_strdup(dialect);
	}

	if (query) {
		filter->query = u_strdup(query);
	} else if(epr != 0) {
		filter->epr = epr_copy(epr);
		filter->assocType = assocType;
		if(assocClass)
			filter->assocClass = u_strdup(assocClass);
		if(resultClass)
			filter->resultClass = u_strdup(resultClass);
		if(role)
			filter->role = u_strdup(role);
		if(resultRole)
			filter->resultRole = u_strdup(resultRole);
		if(resultProp && propNum) {
			filter->resultProp = u_malloc(propNum*sizeof(char *));
			filter->PropNum = propNum;
			while(i < propNum) {
				filter->resultProp[i] = u_strdup(resultProp[i]);
				i++;
			}
		}
	} else if(selectors) {
		hnode_t        *hn;
		hscan_t         hs;
		Selector *p;
		selector_entry *entry;
		filter->selectorset.count = hash_count(selectors);
		filter->selectorset.selectors = u_malloc(sizeof(Selector)*
			filter->selectorset.count);

		p = filter->selectorset.selectors;
		hash_scan_begin(&hs, selectors);
		while ((hn = hash_scan_next(&hs))) {
			p->name = u_strdup((char *)hnode_getkey(hn));
			entry = (selector_entry *)hnode_get(hn);
			if(entry->type == 1) {
				p->type = 1;
				p->value = (char *)epr_copy(entry->entry.eprp);
				debug("key = %s value=%p(nested epr)",
					(char *) hnode_getkey(hn), p->value);
			} else {
				p->type = 0;
				p->value = u_strdup(entry->entry.text);
				debug("key = %s value=%s",
					(char *) hnode_getkey(hn), p->value);
			}
			p++;
		}
	}
	else
		goto cleanup;
	return 0;
cleanup:
	return 1;
}

filter_t *filter_create(const char *dialect, const char *query, epr_t *epr, hash_t *selectors,
	const int assocType, const char *assocClass, const char *resultClass, const char *role,
	const char *resultRole, char **resultProp, const int propNum)
{
	int ret = 0;
	filter_t *filter = filter_initialize();
	if (filter == NULL)
		return NULL;
	ret = filter_set(filter, dialect, query, epr, selectors,
		    assocType, assocClass, resultClass, role, resultRole, resultProp, propNum);
	if (ret == 1 ) {
		filter_destroy(filter);
		return NULL;
	} else {
		return filter;
	}
}

int filter_set_simple(filter_t *filter, const char *dialect, const char *query)
{
	return filter_set(filter, dialect, query, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0);
}

filter_t * filter_create_simple(const char *dialect, const char *query)
{
	return filter_create(dialect, query, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0);
}

int filter_set_assoc(filter_t *filter, epr_t *epr, const int assocType, const char *assocClass,
	const char *resultClass, const char *role, const char *resultRole, char **resultProp,
	const int propNum)
{
	return filter_set(filter, WSM_ASSOCIATION_FILTER_DIALECT, NULL, epr, NULL, assocType,
		assocClass, resultClass, role, resultRole, resultProp, propNum);
}


filter_t * filter_create_assoc(epr_t *epr, const int assocType, const char *assocClass,
	const char *resultClass, const char *role, const char *resultRole, char **resultProp,
	const int propNum)
{
	return filter_create(WSM_ASSOCIATION_FILTER_DIALECT, NULL, epr, NULL, assocType,
		assocClass, resultClass, role, resultRole, resultProp, propNum);
}

filter_t * filter_create_selector(hash_t *selectors)
{
	return filter_create(WSM_SELECTOR_FILTER_DIALECT, NULL, NULL, selectors, 0,
		NULL, NULL, NULL, NULL, NULL, 0);
}

int filter_add_selector(filter_t *filter, const char* key, const char *value)
{
	int i;
	Selector *entry;
	if(filter == NULL || key == NULL || value == NULL)
		return 0;
	entry = filter->selectorset.selectors;
	for(i = 0; i < filter->selectorset.count; i++) {
		if(strcmp(key, entry[i].name) == 0)
			return -1;
	}
	entry = u_realloc(entry, (filter->selectorset.count+1) * sizeof(Selector));
	if(entry == NULL) return -1;

	entry[filter->selectorset.count].type = 0;
	entry[filter->selectorset.count].name = u_strdup(key);
	entry[filter->selectorset.count].value = u_strdup(value);
	filter->selectorset.selectors = entry;
	filter->selectorset.count++;

	return 0;

}

filter_t * filter_copy(filter_t *filter)
{
	filter_t *filter_cpy = NULL;
	Selector *p1;
	Selector *p2;
	int i = 0;
	if(filter == NULL)
		return NULL;
	filter_cpy = u_zalloc(sizeof(filter_t));
	if(filter_cpy == NULL)
		return NULL;

	if(filter->dialect)
		filter_cpy->dialect = u_strdup(filter->dialect);
	filter_cpy->assocType = filter->assocType;
	if(filter->epr)
		filter_cpy->epr = epr_copy(filter->epr);
	if(filter->query)
		filter_cpy->query = u_strdup(filter->query);

	filter_cpy->selectorset.count = filter->selectorset.count;
	filter_cpy->selectorset.selectors = u_malloc(sizeof(Selector) *
		filter->selectorset.count);
	p1 = filter->selectorset.selectors;
	p2 = filter_cpy->selectorset.selectors;
	for(i = 0; i < filter_cpy->selectorset.count; i++) {
		p2->name = u_strdup(p1->name);
		p2->type = p1->type;
		if(p1->type == 0)
			p2->value = u_strdup(p1->value);
		else
			p2->value = (char *)epr_copy((epr_t*)p1->value);
		p1++;
		p2++;
	}

	if(filter->assocClass)
		filter_cpy->assocClass = u_strdup(filter->assocClass);
	if(filter->resultClass)
		filter_cpy->resultClass = u_strdup(filter->resultClass);
	if(filter->resultRole)
		filter_cpy->resultRole = u_strdup(filter->resultRole);
	if(filter->resultProp) {
		int i = 0;
		filter_cpy->resultProp = u_malloc(filter->PropNum*sizeof(char *));
		filter_cpy->PropNum = filter->PropNum;
		while(i < filter->PropNum) {
			filter_cpy->resultProp[i] = u_strdup(filter->resultProp[i]);
			i++;
		}
	}
	return filter_cpy;
}

void filter_destroy(filter_t *filter)
{
	Selector *p;
	int i;
	if(filter == NULL)
		return;
	if(filter->assocClass)
		u_free(filter->assocClass);
	if(filter->dialect)
		u_free(filter->dialect);
	if(filter->query)
		u_free(filter->query);
	if(filter->epr)
		epr_destroy(filter->epr);

	p = filter->selectorset.selectors;
	for(i = 0; i< filter->selectorset.count; i++) {
		u_free(p->name);
		if(p->type == 0)
			u_free(p->value);
		else
			epr_destroy((epr_t*)p->value);
		p++;
	}
	u_free(filter->selectorset.selectors);

	if(filter->resultClass)
		u_free(filter->resultClass);
	if(filter->resultProp) {
		int i = 0;
		while(i < filter->PropNum) {
			u_free(filter->resultProp[i]);
			i++;
		}
		u_free(filter->resultProp);
	}
	if(filter->resultRole)
		u_free(filter->resultRole);
	if(filter->role)
		u_free(filter->role);
	u_free(filter);
}

int filter_serialize(WsXmlNodeH node, filter_t *filter, const char *ns)
{
	int r = 0;
	WsXmlNodeH filter_node = NULL;
	WsXmlNodeH instance_node = NULL;
	if(filter->query) {
		filter_node = ws_xml_add_child(node, ns, WSM_FILTER, filter->query);
	} else if(filter->epr) {
		filter_node = ws_xml_add_child(node, ns, WSM_FILTER, NULL);
		if(filter->assocType == 0)
			instance_node = ws_xml_add_child(filter_node, XML_NS_CIM_BINDING, WSMB_ASSOCIATED_INSTANCES, NULL);
		else
			instance_node = ws_xml_add_child(filter_node, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_INSTANCES, NULL);
		r = epr_serialize(instance_node, XML_NS_CIM_BINDING, WSMB_OBJECT, filter->epr, 1);

		if(r)
			return r;
		if(filter->assocClass)
			ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_CLASS_NAME,
			filter->assocClass);
		if(filter->role)
			ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_ROLE, filter->role);
		if(filter->resultClass)
			ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_RESULT_CLASS_NAME,
			filter->resultClass);
		if(filter->resultRole)
			ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_RESULT_ROLE, filter->resultRole);
		if(filter->resultProp) {
			int i = 0;
			while(i < filter->PropNum) {
				ws_xml_add_child(instance_node, XML_NS_CIM_BINDING, WSMB_INCLUDE_RESULT_PROPERTY,
					filter->resultProp[i]);
				i++;
			}
		}

	} else if(filter->selectorset.count) {
		int i = 0;
		filter_node = ws_xml_add_child(node, ns, WSM_FILTER, NULL);
		node = ws_xml_add_child(filter_node, XML_NS_WS_MAN, WSM_SELECTOR_SET, NULL);

		while (i < filter->selectorset.count) {
			if(filter->selectorset.selectors[i].type == 0) {
				instance_node = ws_xml_add_child(node, XML_NS_WS_MAN, WSM_SELECTOR,
					filter->selectorset.selectors[i].value);
				ws_xml_add_node_attr(instance_node, NULL, WSM_NAME, filter->selectorset.selectors[i].name);
			}
			else {
				epr_serialize(node, NULL, NULL, (epr_t *)filter->selectorset.selectors[i].value, 1);
			}
			i++;
		}
	}
	else {
		return -1;
	}
	if(filter->dialect)
		ws_xml_add_node_attr(filter_node, NULL, WSM_DIALECT, filter->dialect);
	return r;

}

filter_t * filter_deserialize(WsXmlNodeH node, const char *ns)
{
	char *dialect = NULL;
	int properNum = 0;
	int i = 0;
	WsXmlAttrH attr = NULL;
	filter_t *filter = NULL;
	WsXmlNodeH instance_node = NULL;
	WsXmlNodeH entry_node = NULL;
        /* look for wse:Filter */
	WsXmlNodeH filter_node = ws_xml_get_child(node, 0, ns, WSM_FILTER);
	if(filter_node == NULL) return NULL;
	filter = u_zalloc(sizeof(filter_t));
	dialect = ws_xml_find_attr_value(filter_node, NULL, WSM_DIALECT);
	if(dialect)
		filter->dialect = u_strdup(dialect);
	else{
		attr = ws_xml_get_node_attr(filter_node, 0);
		if(attr) {
			filter->dialect = u_strdup(ws_xml_get_attr_value(attr));
		}
		else
			filter->dialect = u_strdup(WSM_XPATH_FILTER_DIALECT);
	}
	if(strcmp(filter->dialect , WSM_ASSOCIATION_FILTER_DIALECT) == 0) {
		instance_node = ws_xml_get_child(filter_node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATED_INSTANCES);
		if(instance_node) {
			filter->assocType = 0;
		}
		else {
			instance_node = ws_xml_get_child(filter_node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_INSTANCES);
			if(instance_node) {
				filter->assocType = 1;
			}
			else
				goto CLEANUP;
		}
		filter->epr = epr_deserialize(instance_node, XML_NS_CIM_BINDING, WSMB_OBJECT, 1);
		entry_node = ws_xml_get_child(instance_node, 0, XML_NS_CIM_BINDING, WSMB_ASSOCIATION_CLASS_NAME);
		if(entry_node)
			filter->assocClass = u_strdup(ws_xml_get_node_text(entry_node));
		entry_node = ws_xml_get_child(instance_node, 0, XML_NS_CIM_BINDING, WSMB_ROLE);
		if(entry_node)
			filter->role = u_strdup(ws_xml_get_node_text(entry_node));
		entry_node = ws_xml_get_child(instance_node, 0, XML_NS_CIM_BINDING, WSMB_RESULT_CLASS_NAME);
		if(entry_node)
			filter->resultClass = u_strdup(ws_xml_get_node_text(entry_node));
		entry_node = ws_xml_get_child(instance_node, 0, XML_NS_CIM_BINDING, WSMB_RESULT_ROLE);
		if(entry_node)
			filter->resultRole = u_strdup(ws_xml_get_node_text(entry_node));
		properNum = ws_xml_get_child_count(instance_node) - 4;
		filter->resultProp = u_zalloc(properNum * sizeof(char*));
		while(i < properNum) {
			filter_node = ws_xml_get_child(instance_node, i, XML_NS_CIM_BINDING, WSMB_INCLUDE_RESULT_PROPERTY);
			if(filter_node == NULL)
				break;
			filter->resultProp[i] = u_strdup(ws_xml_get_node_text(filter_node));
			i++;
		}
		filter->PropNum = i;
	}
	else if(strcmp(filter->dialect, WSM_SELECTOR_FILTER_DIALECT) == 0) {
		filter_node = ws_xml_get_child(filter_node, 0, XML_NS_WS_MAN, WSM_SELECTOR_SET);
		if(filter_node == NULL)
			goto CLEANUP;
		filter->selectorset.count = ws_xml_get_child_count(filter_node);
		filter->selectorset.selectors = u_malloc(sizeof(Selector) * filter->selectorset.count );
		while(i < filter->selectorset.count) {
			entry_node = ws_xml_get_child(filter_node, i, XML_NS_WS_MAN, WSM_SELECTOR);
			if(entry_node == NULL) break;
			attr = ws_xml_find_node_attr(entry_node, NULL, WSM_NAME);
			if(attr) {
				filter->selectorset.selectors[i].name = u_strdup(ws_xml_get_attr_value(attr));
			}
			instance_node = ws_xml_get_child(entry_node, 0, XML_NS_ADDRESSING, WSA_EPR);
			if(instance_node) {
				filter->selectorset.selectors[i].type = 1;
				filter->selectorset.selectors[i].value = (char *)epr_deserialize(instance_node, NULL, NULL, 1);
			}
			else {
				filter->selectorset.selectors[i].type = 0;
				filter->selectorset.selectors[i].value = u_strdup(ws_xml_get_node_text(entry_node));
			}
			i++;
		}
	}
	else
		filter->query = u_strdup(ws_xml_get_node_text(filter_node));

	return filter;

CLEANUP:
	filter_destroy(filter);
	return NULL;
}
