/*
 * Generic XML helper functions
 * Copyright (c) 2012-2013, Qualcomm Atheros, Inc.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "xml-utils.h"


static xml_node_t * get_node_uri_iter(struct xml_node_ctx *ctx,
				      xml_node_t *root, char *uri)
{
	char *end;
	xml_node_t *node;
	const char *name;

	end = strchr(uri, '/');
	if (end)
		*end++ = '\0';

	node = root;
	xml_node_for_each_sibling(ctx, node) {
		xml_node_for_each_check(ctx, node);
		name = xml_node_get_localname(ctx, node);
		if (strcasecmp(name, uri) == 0)
			break;
	}

	if (node == NULL)
		return NULL;

	if (end) {
		return get_node_uri_iter(ctx, xml_node_first_child(ctx, node),
					 end);
	}

	return node;
}


xml_node_t * get_node_uri(struct xml_node_ctx *ctx, xml_node_t *root,
			  const char *uri)
{
	char *search;
	xml_node_t *node;

	search = os_strdup(uri);
	if (search == NULL)
		return NULL;

	node = get_node_uri_iter(ctx, root, search);

	os_free(search);
	return node;
}


static xml_node_t * get_node_iter(struct xml_node_ctx *ctx,
				  xml_node_t *root, const char *path)
{
	char *end;
	xml_node_t *node;
	const char *name;

	end = os_strchr(path, '/');
	if (end)
		*end++ = '\0';

	xml_node_for_each_child(ctx, node, root) {
		xml_node_for_each_check(ctx, node);
		name = xml_node_get_localname(ctx, node);
		if (os_strcasecmp(name, path) == 0)
			break;
	}

	if (node == NULL)
		return NULL;
	if (end)
		return get_node_iter(ctx, node, end);
	return node;
}


xml_node_t * get_node(struct xml_node_ctx *ctx, xml_node_t *root,
		      const char *path)
{
	char *search;
	xml_node_t *node;

	search = os_strdup(path);
	if (search == NULL)
		return NULL;

	node = get_node_iter(ctx, root, search);

	os_free(search);
	return node;
}


xml_node_t * get_child_node(struct xml_node_ctx *ctx, xml_node_t *root,
			    const char *path)
{
	xml_node_t *node;
	xml_node_t *match;

	xml_node_for_each_child(ctx, node, root) {
		xml_node_for_each_check(ctx, node);
		match = get_node(ctx, node, path);
		if (match)
			return match;
	}

	return NULL;
}


xml_node_t * node_from_file(struct xml_node_ctx *ctx, const char *name)
{
	xml_node_t *node;
	char *buf, *buf2, *start;
	size_t len;

	buf = os_readfile(name, &len);
	if (buf == NULL)
		return NULL;
	buf2 = os_realloc(buf, len + 1);
	if (buf2 == NULL) {
		os_free(buf);
		return NULL;
	}
	buf = buf2;
	buf[len] = '\0';

	start = os_strstr(buf, "<!DOCTYPE ");
	if (start) {
		char *pos = start + 1;
		int count = 1;
		while (*pos) {
			if (*pos == '<')
				count++;
			else if (*pos == '>') {
				count--;
				if (count == 0) {
					pos++;
					break;
				}
			}
			pos++;
		}
		if (count == 0) {
			/* Remove DOCTYPE to allow the file to be parsed */
			os_memset(start, ' ', pos - start);
		}
	}

	node = xml_node_from_buf(ctx, buf);
	os_free(buf);

	return node;
}


int node_to_file(struct xml_node_ctx *ctx, const char *fname, xml_node_t *node)
{
	FILE *f;
	char *str;

	str = xml_node_to_str(ctx, node);
	if (str == NULL)
		return -1;

	f = fopen(fname, "w");
	if (!f) {
		os_free(str);
		return -1;
	}

	fprintf(f, "%s\n", str);
	os_free(str);
	fclose(f);

	return 0;
}


static char * get_val(struct xml_node_ctx *ctx, xml_node_t *node)
{
	char *val, *pos;

	val = xml_node_get_text(ctx, node);
	if (val == NULL)
		return NULL;
	pos = val;
	while (*pos) {
		if (*pos != ' ' && *pos != '\t' && *pos != '\r' && *pos != '\n')
			return val;
		pos++;
	}

	return NULL;
}


static char * add_path(const char *prev, const char *leaf)
{
	size_t len;
	char *new_uri;

	if (prev == NULL)
		return NULL;

	len = os_strlen(prev) + 1 + os_strlen(leaf) + 1;
	new_uri = os_malloc(len);
	if (new_uri)
		os_snprintf(new_uri, len, "%s/%s", prev, leaf);

	return new_uri;
}


static void node_to_tnds(struct xml_node_ctx *ctx, xml_node_t *out,
			 xml_node_t *in, const char *uri)
{
	xml_node_t *node;
	xml_node_t *tnds;
	const char *name;
	char *val;
	char *new_uri;

	xml_node_for_each_child(ctx, node, in) {
		xml_node_for_each_check(ctx, node);
		name = xml_node_get_localname(ctx, node);

		tnds = xml_node_create(ctx, out, NULL, "Node");
		if (tnds == NULL)
			return;
		xml_node_create_text(ctx, tnds, NULL, "NodeName", name);

		if (uri)
			xml_node_create_text(ctx, tnds, NULL, "Path", uri);

		val = get_val(ctx, node);
		if (val) {
			xml_node_create_text(ctx, tnds, NULL, "Value", val);
			xml_node_get_text_free(ctx, val);
		}

		new_uri = add_path(uri, name);
		node_to_tnds(ctx, new_uri ? out : tnds, node, new_uri);
		os_free(new_uri);
	}
}


static int add_ddfname(struct xml_node_ctx *ctx, xml_node_t *parent,
		       const char *urn)
{
	xml_node_t *node;

	node = xml_node_create(ctx, parent, NULL, "RTProperties");
	if (node == NULL)
		return -1;
	node = xml_node_create(ctx, node, NULL, "Type");
	if (node == NULL)
		return -1;
	xml_node_create_text(ctx, node, NULL, "DDFName", urn);
	return 0;
}


xml_node_t * mo_to_tnds(struct xml_node_ctx *ctx, xml_node_t *mo,
			int use_path, const char *urn, const char *ns_uri)
{
	xml_node_t *root;
	xml_node_t *node;
	const char *name;

	root = xml_node_create_root(ctx, ns_uri, NULL, NULL, "MgmtTree");
	if (root == NULL)
		return NULL;

	xml_node_create_text(ctx, root, NULL, "VerDTD", "1.2");

	name = xml_node_get_localname(ctx, mo);

	node = xml_node_create(ctx, root, NULL, "Node");
	if (node == NULL)
		goto fail;
	xml_node_create_text(ctx, node, NULL, "NodeName", name);
	if (urn)
		add_ddfname(ctx, node, urn);

	node_to_tnds(ctx, use_path ? root : node, mo, use_path ? name : NULL);

	return root;

fail:
	xml_node_free(ctx, root);
	return NULL;
}


static xml_node_t * get_first_child_node(struct xml_node_ctx *ctx,
					 xml_node_t *node,
					 const char *name)
{
	const char *lname;
	xml_node_t *child;

	xml_node_for_each_child(ctx, child, node) {
		xml_node_for_each_check(ctx, child);
		lname = xml_node_get_localname(ctx, child);
		if (os_strcasecmp(lname, name) == 0)
			return child;
	}

	return NULL;
}


static char * get_node_text(struct xml_node_ctx *ctx, xml_node_t *node,
			    const char *node_name)
{
	node = get_first_child_node(ctx, node, node_name);
	if (node == NULL)
		return NULL;
	return xml_node_get_text(ctx, node);
}


static xml_node_t * add_mo_node(struct xml_node_ctx *ctx, xml_node_t *root,
				xml_node_t *node, const char *uri)
{
	char *nodename, *value, *path;
	xml_node_t *parent;

	nodename = get_node_text(ctx, node, "NodeName");
	if (nodename == NULL)
		return NULL;
	value = get_node_text(ctx, node, "Value");

	if (root == NULL) {
		root = xml_node_create_root(ctx, NULL, NULL, NULL,
					    nodename);
		if (root && value)
			xml_node_set_text(ctx, root, value);
	} else {
		if (uri == NULL) {
			xml_node_get_text_free(ctx, nodename);
			xml_node_get_text_free(ctx, value);
			return NULL;
		}
		path = get_node_text(ctx, node, "Path");
		if (path)
			uri = path;
		parent = get_node_uri(ctx, root, uri);
		xml_node_get_text_free(ctx, path);
		if (parent == NULL) {
			printf("Could not find URI '%s'\n", uri);
			xml_node_get_text_free(ctx, nodename);
			xml_node_get_text_free(ctx, value);
			return NULL;
		}
		if (value)
			xml_node_create_text(ctx, parent, NULL, nodename,
					     value);
		else
			xml_node_create(ctx, parent, NULL, nodename);
	}

	xml_node_get_text_free(ctx, nodename);
	xml_node_get_text_free(ctx, value);

	return root;
}


static xml_node_t * tnds_to_mo_iter(struct xml_node_ctx *ctx, xml_node_t *root,
				    xml_node_t *node, const char *uri)
{
	xml_node_t *child;
	const char *name;
	char *nodename;

	xml_node_for_each_sibling(ctx, node) {
		xml_node_for_each_check(ctx, node);

		nodename = get_node_text(ctx, node, "NodeName");
		if (nodename == NULL)
			return NULL;

		name = xml_node_get_localname(ctx, node);
		if (strcmp(name, "Node") == 0) {
			if (root && !uri) {
				printf("Invalid TNDS tree structure - "
				       "multiple top level nodes\n");
				xml_node_get_text_free(ctx, nodename);
				return NULL;
			}
			root = add_mo_node(ctx, root, node, uri);
		}

		child = get_first_child_node(ctx, node, "Node");
		if (child) {
			if (uri == NULL)
				tnds_to_mo_iter(ctx, root, child, nodename);
			else {
				char *new_uri;
				new_uri = add_path(uri, nodename);
				tnds_to_mo_iter(ctx, root, child, new_uri);
				os_free(new_uri);
			}
		}
		xml_node_get_text_free(ctx, nodename);
	}

	return root;
}


xml_node_t * tnds_to_mo(struct xml_node_ctx *ctx, xml_node_t *tnds)
{
	const char *name;
	xml_node_t *node;

	name = xml_node_get_localname(ctx, tnds);
	if (name == NULL || os_strcmp(name, "MgmtTree") != 0)
		return NULL;

	node = get_first_child_node(ctx, tnds, "Node");
	if (!node)
		return NULL;
	return tnds_to_mo_iter(ctx, NULL, node, NULL);
}


xml_node_t * soap_build_envelope(struct xml_node_ctx *ctx, xml_node_t *node)
{
	xml_node_t *envelope, *body;
	xml_namespace_t *ns;

	envelope = xml_node_create_root(
		ctx, "http://www.w3.org/2003/05/soap-envelope", "soap12", &ns,
		"Envelope");
	if (envelope == NULL)
		return NULL;
	body = xml_node_create(ctx, envelope, ns, "Body");
	xml_node_add_child(ctx, body, node);
	return envelope;
}


xml_node_t * soap_get_body(struct xml_node_ctx *ctx, xml_node_t *soap)
{
	xml_node_t *body, *child;

	body = get_node_uri(ctx, soap, "Envelope/Body");
	if (body == NULL)
		return NULL;
	xml_node_for_each_child(ctx, child, body) {
		xml_node_for_each_check(ctx, child);
		return child;
	}
	return NULL;
}
