/*******************************************************************************
 * 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 *));
			if (filter->resultProp) {
				filter->PropNum = propNum;
				while (i < propNum) {
					filter->resultProp[i] = u_strdup(resultProp[i]);
					i++;
				}
			} else {
				filter->PropNum = 0;
			}
		}
	} else if(selectors) {
		hnode_t        *hn;
		hscan_t         hs;
                key_value_t *p;
		key_value_t *entry;
		filter->selectorset.count = hash_count(selectors);
                filter->selectorset.selectors = u_malloc(sizeof(key_value_t)*
			filter->selectorset.count);

		p = filter->selectorset.selectors;
		hash_scan_begin(&hs, selectors);
		while ((hn = hash_scan_next(&hs))) {
                  entry = (key_value_t *)hnode_get(hn);
                  key_value_create((char *)hnode_getkey(hn),
                                   (entry->type == 0)?entry->v.text:NULL,
                                   (entry->type == 1)?entry->v.epr:NULL, p);
			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);
}

static int
_filter_add_selector(filter_t *filter, const char* key, const char *value, const epr_t *epr)
{
        key_value_t *entry;
	if(filter == NULL || key == NULL || ((value == NULL) && (epr == NULL)))
		return 0;
	entry = filter->selectorset.selectors;
	for(unsigned int i = 0; i < filter->selectorset.count; i++) {
		if(strcmp(key, entry[i].key) == 0)
			return -1;
	}
	entry = u_realloc(entry, (filter->selectorset.count+1) * sizeof(key_value_t));
	if(entry == NULL) return -1;
        key_value_create(key, value, epr, &(entry[filter->selectorset.count]));
	filter->selectorset.selectors = entry;
	filter->selectorset.count++;

	return 0;

}

int filter_add_selector(filter_t *filter, const char* key, const char *value)
{
  return _filter_add_selector(filter, key, value, NULL);
}

int filter_add_selector_epr(filter_t *filter, const char* key, const epr_t *value)
{
  return _filter_add_selector(filter, key, NULL, value);
}

filter_t * filter_copy(filter_t *filter)
{
	filter_t *filter_cpy = NULL;
	key_value_t *p1;
        key_value_t *p2;
	unsigned 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(key_value_t) *
		filter->selectorset.count);
	if (filter_cpy->selectorset.selectors) {
		p1 = filter->selectorset.selectors;
		p2 = filter_cpy->selectorset.selectors;
		for (i = 0; i < filter_cpy->selectorset.count; i++) {
			key_value_copy(p1, p2);
			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 *));
		if (filter_cpy->resultProp != NULL) {
			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)
{
	key_value_t *p;
	unsigned 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++) {
          key_value_destroy(p, 1);
		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_node)
			return -1;
		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);
		if (!instance_node)
			return -1;

		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) {
		unsigned int i = 0;
		filter_node = ws_xml_add_child(node, ns, WSM_FILTER, NULL);
		if (!filter_node)
			return -1;
		node = ws_xml_add_child(filter_node, XML_NS_WS_MAN, WSM_SELECTOR_SET, NULL);
		if (!node)
			return -1;

		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].v.text);
				ws_xml_add_node_attr(instance_node, NULL, WSM_NAME, filter->selectorset.selectors[i].key);
			}
			else {
				epr_serialize(node, NULL, NULL, (epr_t *)filter->selectorset.selectors[i].v.epr, 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;
	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));
	if (filter == NULL) {
		return NULL;
	}
	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) {
		int i = 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_safe(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_safe(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_safe(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_safe(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_safe(filter_node));
			i++;
		}
		filter->PropNum = i;
	}
	else if(strcmp(filter->dialect, WSM_SELECTOR_FILTER_DIALECT) == 0) {
		unsigned int i = 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(key_value_t) * filter->selectorset.count );
		while(i < filter->selectorset.count) {
                  const char *key;
                  const char *text;
                  epr_t *epr;
			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) {
				key = ws_xml_get_attr_value(attr);
			}
                  else {                          
                    key = NULL;
                  }
			instance_node = ws_xml_get_child(entry_node, 0, XML_NS_ADDRESSING, WSA_EPR);
			if(instance_node) {
				epr = epr_deserialize(instance_node, NULL, NULL, 1);
                          text = NULL;
			}
			else {
				text = ws_xml_get_node_text_safe(entry_node);
                          epr = NULL;
			}
                  key_value_create(key, text, epr, filter->selectorset.selectors + i);
                  if (epr) { /* key_value_create() did a epr_copy */
                    epr_destroy(epr);
                  }
			i++;
		}
	}
	else
		filter->query = u_strdup(ws_xml_get_node_text_safe(filter_node));

	return filter;

CLEANUP:
	filter_destroy(filter);
	return NULL;
}
