/*******************************************************************************
 * 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 Anas Nashif, Intel Corp.
 * @author Liang Hou, Intel Corp.
 */


#ifdef HAVE_CONFIG_H
#include <wsman_config.h>
#endif

#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <assert.h>

#include "u/libu.h"
#include "wsman-xml-api.h"
#include "wsman-client-api.h"
#include "wsman-soap.h"
#include "wsman-xml.h"

#include "wsman-faults.h"
#include "wsman-soap-envelope.h"

#include "wsman-epr.h"

char *wsman_epr_selector_by_name(epr_t *epr, const char* name)
{
	int i;
	char *value = NULL;
	Selector *ss = (Selector *) epr->refparams.selectorset.selectors;
	if (ss == NULL) {
			debug("epr->refparams.selectors.data == NULL\n");
		return NULL;
	}
	for (i = 0; i < epr->refparams.selectorset.count; i++) {
		Selector *s;
		s = ss + i;
		if (strcmp(s->name, name) == 0 && s->type == 0) {
				value =  u_strdup(s->value);
				break;
		}
	}
	return value;
}


void wsman_epr_selector_cb(epr_t *epr, selector_callback cb, void *cb_data)
{
	int i;
	Selector *ss = (Selector *) epr->refparams.selectorset.selectors;
	if (ss == NULL) {
		debug("epr->refparams.selectors == NULL\n");
		return;
	}
	for (i = 0; i < epr->refparams.selectorset.count; i++) {
		Selector *s;
		s = ss + i;
		cb(cb_data, s->name, s->value);
	}
}

void wsman_selectorset_cb(SelectorSet *selectorset, selector_callback cb, void *cb_data)
{
	int i;
	Selector *ss = selectorset->selectors;
	if (ss == NULL) {
		debug("epr->refparams.selectors == NULL");
		return;
	}
	for (i = 0; i < selectorset->count; i++) {
		Selector *s;
		s = ss + i;
		cb(cb_data, s->name, s->value);
	}
}

epr_t *epr_create(const char *uri, hash_t * selectors, const char *address)
{
	epr_t *epr = NULL;
	epr = u_malloc(sizeof(epr_t));
	if (address == NULL)
		epr->address = u_strdup(WSA_TO_ANONYMOUS);
	else
		epr->address = u_strdup(address);

	epr->refparams.uri = u_strdup(uri);

	if (selectors) {
		hnode_t        *hn;
		hscan_t         hs;
		Selector *p;
		selector_entry *entry;
		epr->refparams.selectorset.count = hash_count(selectors);
		epr->refparams.selectorset.selectors = u_malloc(sizeof(Selector)*
			epr->refparams.selectorset.count);

		p = epr->refparams.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 == 0) {
				p->type = 0;
				p->value = u_strdup(entry->entry.text);
				debug("key=%s value=%s",
					(char *) hnode_getkey(hn), p->value);
			}
			else {
				p->type = 1;
				p->value = (char *)epr_copy(entry->entry.eprp);
				debug("key=%s value=%p(nested epr)",
					(char *) hnode_getkey(hn), p->value);
			}
			p++;
		}
	} else {
		epr->refparams.selectorset.count  = 0;
		epr->refparams.selectorset.selectors  = NULL;
	}
	return epr;
}

 epr_t *epr_from_string(const char* str)
 {
 	char *p;
	char *uri;
	hash_t *selectors = NULL;
	hash_t *selectors_new = NULL;
	hnode_t        *hn;
	hscan_t         hs;
	selector_entry *entry;
	epr_t *epr;

	p = strchr(str, '?');
        if (p) {
          uri = u_strndup(str, p - str);
          selectors = u_parse_query(p + 1);
          selectors_new = hash_create2(HASHCOUNT_T_MAX, 0, 0);
	  hash_scan_begin(&hs, selectors);
	  while ((hn = hash_scan_next(&hs))) {
		entry = u_malloc(sizeof(selector_entry));
		entry->type = 0;
		entry->entry.text = (char *)hnode_get(hn);
		hash_alloc_insert(selectors_new, hnode_getkey(hn), entry);
	  }
        }
        else {
          uri = u_strdup(str);
        }

	epr = epr_create(uri, selectors_new, NULL);
        if (selectors_new) {
	  hash_free(selectors_new);
          hash_free(selectors);
        }
	u_free(uri);
	return epr;
 }

static int epr_add_selector(epr_t *epr, const char *name, selector_entry *selector)
 {
 	int i;
 	Selector *p;
	if(epr == NULL) return 0;
 	p = epr->refparams.selectorset.selectors;
	for(i = 0; i< epr->refparams.selectorset.count; i++) {
		if(p->name && ( strcmp(name, p->name) == 0 ) ) {
			return -1;
		}
		p++;
	}
	p = epr->refparams.selectorset.selectors;
	p = u_realloc(p, (epr->refparams.selectorset.count+1) * sizeof(Selector));
	if(p == NULL) return -1;
	p[epr->refparams.selectorset.count].name = u_strdup(name);
	p[epr->refparams.selectorset.count].type = selector->type;
	if(selector->type == 0) {
		if (selector->entry.text) {
			p[epr->refparams.selectorset.count].value = u_strdup(selector->entry.text);
		}
	} else {
		p[epr->refparams.selectorset.count].value = (char *)epr_copy(selector->entry.eprp);
	}

	epr->refparams.selectorset.selectors = p;
	epr->refparams.selectorset.count++;
	return 0;
 }

int epr_selector_count(epr_t *epr) {
	if(epr == NULL) return 0;
	return epr->refparams.selectorset.count;
}

int epr_add_selector_text(epr_t *epr, const char *name, const char *text)
{
	int r;
	selector_entry *entry;
	entry = u_malloc(sizeof(selector_entry));
	entry->type = 0;
	entry->entry.text = (char *)text;
	r = epr_add_selector(epr, name, entry);
	u_free(entry);
	return r;
}

int epr_add_selector_epr(epr_t *epr, const char *name, epr_t *added_epr)
{
	int r;
	selector_entry *entry;
	entry = u_malloc(sizeof(selector_entry));
	entry->type = 1;
	entry->entry.eprp = added_epr;
	r = epr_add_selector(epr, name, entry);
	u_free(entry);
	return r;
}

int epr_delete_selector(epr_t *epr, const char *name)
{
	int i,k;
	int count;
	Selector *selectors;
	if(epr == NULL || name == NULL) return 0;
	count = epr->refparams.selectorset.count;
	selectors = epr->refparams.selectorset.selectors;
	for(i =0; i < count; i++) {
		if(strcmp(name, selectors[i].name) == 0)
			break;
	}
	if(i == count) return -1;

	u_free(selectors[i].name);
	if(selectors[i].type == 0) {
		u_free(selectors[i].value);
	}
	else {
		epr_destroy((epr_t *)selectors[i].value);
	}

	for(k = i; k < count-1; k++) {
		memcpy(&selectors[k], &selectors[k+1], sizeof(Selector));
	}

	epr->refparams.selectorset.selectors = u_realloc(selectors, (count-1)*sizeof(Selector));
	epr->refparams.selectorset.count--;

	return 0;
}

void epr_destroy(epr_t *epr)
{
	int i;
	Selector *p;
	if(epr == NULL) return;
	u_free(epr->address);
	u_free(epr->refparams.uri);
	p = epr->refparams.selectorset.selectors;
	for(i = 0; i< epr->refparams.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(epr->refparams.selectorset.selectors);
	u_free(epr);

}

epr_t *epr_copy(epr_t *epr)
{
	int i;
	Selector *p1;
	Selector *p2;
	epr_t *cpy_epr = NULL;
	if(epr == NULL)
		return cpy_epr;

	cpy_epr = u_malloc(sizeof(epr_t));
	if (epr && epr->address)
		cpy_epr->address = u_strdup(epr->address);

	cpy_epr->refparams.uri = u_strdup(epr->refparams.uri);
	cpy_epr->refparams.selectorset.count = epr->refparams.selectorset.count;
	cpy_epr->refparams.selectorset.selectors = u_malloc(sizeof(Selector)*
			epr->refparams.selectorset.count);

	p1 = epr->refparams.selectorset.selectors;
	p2 = cpy_epr->refparams.selectorset.selectors;
	for(i = 0; i < epr->refparams.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++;
	}
	return cpy_epr;
}

 int epr_cmp(epr_t *epr1, epr_t *epr2)
 {
 	int i, j;
 	int matches = 0;
	Selector *p1;
	Selector *p2;
	assert(epr1 != NULL && epr2 != NULL);
	//if(strcmp(epr1->address, epr2->address)) return 1;

	if(strcmp(epr1->refparams.uri, epr2->refparams.uri)) return 1;
	if(epr1->refparams.selectorset.count != epr2->refparams.selectorset.count)
		return 1;
	p1 = epr1->refparams.selectorset.selectors;
	for(i = 0; i < epr1->refparams.selectorset.count; i++) {
		p2 = epr1->refparams.selectorset.selectors;
		for(j = 0; j < epr2->refparams.selectorset.count; j++, p2++) {
			if(strcmp(p1->name, p2->name))
				continue;
			if(p1->type != p2->type)
				continue;
			if(p1->type == 0) {
				if(strcmp(p1->value, p2->value))
					continue;
			} else {
				if (epr_cmp((epr_t*)p1->value, (epr_t*)p2->value) == 1) {
					continue;
				}
			}
			matches++;
		}
		p1++;
	}

	if (matches == epr1->refparams.selectorset.count)
		return 0;
	else
		return 1;
}

char *epr_to_string(epr_t *epr)
{
  int i, len;
  char *buf, *ptr;

  Selector *p = NULL;
  if (epr == NULL) return NULL;

  /* calculate buffer size */
  len = strlen(epr->refparams.uri);

  p = epr->refparams.selectorset.selectors;
  for(i = 0; i < epr->refparams.selectorset.count; i++) {
    len += (strlen(p->name) + 1); /* (?|&)key */
    if (p->type == 0)
      len += (strlen(p->value) + 1); /* =value */
    else {
      char *value = epr_to_string((epr_t *)p->value);
      if (value) {
        len += (strlen(value) + 1); /* =value */
        u_free(value);
      }
    }
    p++;
  }
  buf = u_malloc(len + 1);
  strcpy(buf, epr->refparams.uri);
  ptr = buf + strlen(buf);
  p = epr->refparams.selectorset.selectors;
  for(i = 0; i < epr->refparams.selectorset.count; i++) {
    if (i == 0)
      *ptr++ = '?';
    else
      *ptr++ = '&';
    strcpy(ptr, p->name);
    ptr += strlen(p->name);
    *ptr++ = '=';
    if (p->type == 0) {
      strcpy(ptr, p->value);
      ptr += strlen(p->value);
    } else {
      char *value = epr_to_string((epr_t *)p->value);
      if (value) {
        strcpy(ptr, value);
        ptr += strlen(value);
        u_free(value);
      }
    }
    p++;
  }
  *ptr++ = 0;
  return buf;
}


char *epr_to_txt(epr_t *epr, const char *ns, const char*epr_node_name)
{
	char *buf = NULL;
	int len;
	WsXmlDocH doc2;
	WsXmlDocH doc = ws_xml_create_doc(ns, epr_node_name);
	WsXmlNodeH rootNode = ws_xml_get_doc_root(doc);
	epr_serialize(rootNode, NULL, NULL, epr, 1);
	doc2 = ws_xml_create_doc_by_import( rootNode);
	ws_xml_dump_memory_node_tree(ws_xml_get_doc_root(doc), &buf, &len);
	ws_xml_destroy_doc(doc);;
	ws_xml_destroy_doc(doc2);
	return buf;
}


char *epr_get_resource_uri(epr_t *epr) {
	if (epr)
		return epr->refparams.uri;
	else
		return NULL;
}

int epr_serialize(WsXmlNodeH node, const char *ns,
		const char *epr_node_name, epr_t *epr, int embedded)
{
	int i;
	WsXmlNodeH eprnode = NULL;
	WsXmlNodeH refparamnode = NULL;
	WsXmlNodeH selectorsetnode = NULL;
	Selector *p = NULL;
	if(epr == NULL) return 0;

	if(epr_node_name) {
		eprnode = ws_xml_add_child(node, ns, epr_node_name, NULL);
	}
	else
		eprnode = node;
	if(embedded)
		ws_xml_add_child(eprnode, XML_NS_ADDRESSING, WSA_ADDRESS, epr->address);
	else
		ws_xml_add_child(eprnode, XML_NS_ADDRESSING, WSA_TO, epr->address);
	if(embedded)
		refparamnode = ws_xml_add_child(eprnode, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS, NULL);
	else
		refparamnode = node;

	ws_xml_add_child(refparamnode, XML_NS_WS_MAN, WSM_RESOURCE_URI, epr->refparams.uri);
	selectorsetnode = ws_xml_add_child(refparamnode, XML_NS_WS_MAN, WSM_SELECTOR_SET, NULL);

	p = epr->refparams.selectorset.selectors;
	for(i = 0; i < epr->refparams.selectorset.count; i++) {
		WsXmlNodeH temp = NULL;
		if(p->type == 0)
			temp = ws_xml_add_child(selectorsetnode, XML_NS_WS_MAN, WSM_SELECTOR, p->value);
		else {
			temp = ws_xml_add_child(selectorsetnode, XML_NS_WS_MAN, WSM_SELECTOR, NULL);
			epr_serialize(temp, XML_NS_ADDRESSING, WSA_EPR, (epr_t *)p->value, 1);
		}
		ws_xml_add_node_attr(temp, NULL, WSM_NAME, p->name);
		p++;
	}
	return 0;
}

epr_t *epr_deserialize(WsXmlNodeH node, const char *ns,
		const char *epr_node_name, int embedded)
{
	int i;
	epr_t *epr = u_malloc(sizeof(epr_t));

	WsXmlNodeH eprnode = NULL;
	WsXmlNodeH refparamnode = NULL;
	WsXmlNodeH temp = NULL;
	WsXmlNodeH selectorsetnode = NULL;
	WsXmlAttrH attr = NULL;
	Selector *p = NULL;

	if(epr_node_name) {
		eprnode = ws_xml_get_child(node, 0, ns, epr_node_name);
		if(eprnode == NULL)
			goto CLEANUP;
	} else {
		eprnode = node;
	}

	if(embedded) {
		temp = ws_xml_get_child(eprnode, 0, XML_NS_ADDRESSING, WSA_ADDRESS);
	} else {
		temp = ws_xml_get_child(eprnode, 0, XML_NS_ADDRESSING, WSA_TO);
	}

	if(temp == NULL)
		goto CLEANUP;
	epr->address = u_strdup(ws_xml_get_node_text(temp));

	if(embedded) {
		refparamnode = ws_xml_get_child(eprnode, 0, XML_NS_ADDRESSING, WSA_REFERENCE_PARAMETERS);
	} else {
		refparamnode = node;
	}

	if(refparamnode == NULL)
		goto CLEANUP;

	temp = ws_xml_get_child(refparamnode, 0, XML_NS_WS_MAN, WSM_RESOURCE_URI);
	if(temp == NULL)
		goto CLEANUP;

	epr->refparams.uri = u_strdup(ws_xml_get_node_text(temp));

	selectorsetnode = ws_xml_get_child(refparamnode, 0, XML_NS_WS_MAN, WSM_SELECTOR_SET);
	epr->refparams.selectorset.count = ws_xml_get_child_count(selectorsetnode);
	epr->refparams.selectorset.selectors = u_malloc(epr->refparams.selectorset.count *
		 sizeof(Selector));

	p = epr->refparams.selectorset.selectors;
	for(i = 0; i < epr->refparams.selectorset.count; i++) {
		temp = ws_xml_get_child(selectorsetnode, i, XML_NS_WS_MAN, WSM_SELECTOR);
		attr = ws_xml_find_node_attr(temp, NULL, "Name");
		if(attr) {
			p->name = u_strdup(ws_xml_get_attr_value(attr));
		}
		if(ws_xml_get_child(temp, 0, XML_NS_ADDRESSING, WSA_EPR)) {
			p->type = 1;
			p->value = (char *)epr_deserialize(temp, XML_NS_ADDRESSING, WSA_EPR, 1);
		} else {
			p->type = 0;
			p->value = u_strdup(ws_xml_get_node_text(temp));
		}
		p++;
	}

	return epr;
CLEANUP:
	u_free(epr);
	return NULL;

}

char *get_cimnamespace_from_selectorset(SelectorSet *selectorset)
{
	int i = 0;
	while(i < selectorset->count) {
		if(strcmp(selectorset->selectors[i].name, CIM_NAMESPACE_SELECTOR) == 0)
			return selectorset->selectors[i].value;
		i++;
	}
	return NULL;
}

