/*******************************************************************************
 * 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(const epr_t *epr, const char* name)
{
	int i;
	char *value = NULL;
	key_value_t *ss = epr->refparams.selectorset.selectors;
	if (ss == NULL) {
			debug("epr->refparams.selectorset.selectors == NULL\n");
		return NULL;
	}
	for (i = 0; i < epr->refparams.selectorset.count; i++) {
		key_value_t *s;
		s = ss + i;
		if (strcmp(s->key, name) == 0 && s->type == 0) {
				value =  u_strdup(s->v.text);
				break;
		}
	}
	return value;
}


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

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

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;
		key_value_t *p;
		key_value_t *entry;
		epr->refparams.selectorset.count = hash_count(selectors);
		epr->refparams.selectorset.selectors = u_malloc(sizeof(key_value_t)*
			epr->refparams.selectorset.count);

		p = epr->refparams.selectorset.selectors;
		hash_scan_begin(&hs, selectors);
		while ((hn = hash_scan_next(&hs))) {
                  entry = (key_value_t *)hnode_get(hn);
                  if (entry->type == 0) {
                    key_value_create((char *)hnode_getkey(hn), entry->v.text, NULL, p);
                    debug("key=%s value=%s", p->key, p->v.text);
                  }
                  else {
                    key_value_create((char *)hnode_getkey(hn), NULL, entry->v.epr, p);
                    debug("key=%s value=%p(nested epr)", p->key, p->v.epr);
                  }
                  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;
	key_value_t *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 = key_value_create(NULL, (char *)hnode_get(hn), NULL, NULL);
		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, const char *text, epr_t *added_epr)
{
	int i;
        key_value_t *p, *new_p;
	if (epr == NULL) return 0;
	p = epr->refparams.selectorset.selectors;
	for(i = 0; i< epr->refparams.selectorset.count; i++) {
		if(p->key && ( strcmp(name, p->key) == 0 ) ) {
			return -1;
		}
		p++;
	}
	p = epr->refparams.selectorset.selectors;
	p = u_realloc(p, (epr->refparams.selectorset.count+1) * sizeof(key_value_t));
	if (p == NULL) return -1;
        new_p = key_value_create(name, text, added_epr, &(p[epr->refparams.selectorset.count]));

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

int epr_selector_count(const 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)
{
	return epr_add_selector(epr, name, text, NULL);
}

int epr_add_selector_epr(epr_t *epr, const char *name, epr_t *added_epr)
{
	return epr_add_selector(epr, name, NULL, added_epr);
}

int epr_delete_selector(epr_t *epr, const char *name)
{
	int i,k;
	int count;
	key_value_t *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].key) == 0)
			break;
	}
	if(i == count) return -1;

        key_value_destroy(&selectors[i], 1);

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

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

	return 0;
}

void epr_destroy(epr_t *epr)
{
	int i;
	key_value_t *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++) {
          key_value_destroy(p, 1);
		p++;
	}

	u_free(epr->refparams.selectorset.selectors);
	u_free(epr);

}

epr_t *epr_copy(const epr_t *epr)
{
	int i;
	key_value_t *p1;
	key_value_t *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(key_value_t)*
			epr->refparams.selectorset.count);

	p1 = epr->refparams.selectorset.selectors;
	p2 = cpy_epr->refparams.selectorset.selectors;
	for (i = 0; i < epr->refparams.selectorset.count; i++) {
          key_value_copy(p1, p2);
		p1++;
		p2++;
	}
	return cpy_epr;
}

int epr_cmp(const epr_t *epr1, const epr_t *epr2)
{
	int i, j;
	int matches = 0;
	key_value_t *p1;
	key_value_t *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->key, p2->key))
				continue;
			if(p1->type != p2->type)
				continue;
			if(p1->type == 0) {
				if(strcmp(p1->v.text, p2->v.text))
					continue;
			} else {
				if (epr_cmp(p1->v.epr, p2->v.epr) == 1) {
					continue;
				}
			}
			matches++;
		}
		p1++;
	}

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

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

  key_value_t *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->key) + 1); /* (?|&)key */
    if (p->type == 0)
      len += (strlen(p->v.text) + 1); /* =value */
    else {
      char *value = epr_to_string(p->v.epr);
      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->key);
    ptr += strlen(p->key);
    *ptr++ = '=';
    if (p->type == 0) {
      strcpy(ptr, p->v.text);
      ptr += strlen(p->v.text);
    } else {
      char *value = epr_to_string(p->v.epr);
      if (value) {
        strcpy(ptr, value);
        ptr += strlen(value);
        u_free(value);
      }
    }
    p++;
  }
  *ptr++ = 0;
  return buf;
}


char *epr_to_txt(const 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(const 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, const epr_t *epr, int embedded)
{
	int i;
	WsXmlNodeH eprnode = NULL;
	WsXmlNodeH refparamnode = NULL;
	WsXmlNodeH selectorsetnode = NULL;
	key_value_t *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->v.text);
		else {
			temp = ws_xml_add_child(selectorsetnode, XML_NS_WS_MAN, WSM_SELECTOR, NULL);
			epr_serialize(temp, XML_NS_ADDRESSING, WSA_EPR, p->v.epr, 1);
		}
		ws_xml_add_node_attr(temp, NULL, WSM_NAME, p->key);
		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;
	key_value_t *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(key_value_t));

	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->key = u_strdup(ws_xml_get_attr_value(attr));
		}
		if(ws_xml_get_child(temp, 0, XML_NS_ADDRESSING, WSA_EPR)) {
			p->type = 1;
			p->v.epr = epr_deserialize(temp, XML_NS_ADDRESSING, WSA_EPR, 1);
		} else {
			p->type = 0;
			p->v.text = 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].key, CIM_NAMESPACE_SELECTOR) == 0)
			return selectorset->selectors[i].v.text;
		i++;
	}
	return NULL;
}

