/*
 *  evaluate_xml.c (copied from KERNEL source) 
 *
 *    Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
 */

#include "zfcp_dumper.h"
#include "xml.h"
#include "evaluate_xml.h"

#ifndef KERNEL
        #include <string.h>
        #define simple_strtol strtol
#endif

/*
 * return child of type tag_type if there is one
 */
static xml_node_t *get_child(xml_node_t *node, int tag_type)
{
	int num_ch;

	for (num_ch=0; num_ch < node->iNumChild; num_ch++)
		if ((node->ppChild[num_ch])->iTagType == tag_type)
			return node->ppChild[num_ch];
	return NULL;
}


/*
 * return next sibling if there is one
 */
static xml_node_t *get_next_sibling(xml_node_t *node)
{
	int          pos = 0;

	if (!node)
		return NULL;

	while((node->pParent)->ppChild[pos] != node)
		pos++;

	if (pos < ((node->pParent)->iNumChild - 1))
	        return (node->pParent)->ppChild[pos+1];

	return NULL;
}


#if 0
/*
 * search for an attribute attr of the input node
 */
static char *get_attr(xml_node_t *node, char *attr)
{
	int   num_attr;

	if (!node)
		return NULL;

	for (num_attr=0; num_attr < node->iNumAttr; num_attr++)
		if (!strcmp(node->ppszAttrName[num_attr], attr))
			return node->ppszAttrValue[num_attr];
	return NULL;
}
#endif

/*
 * return the body of a node and remove leading & trailing spaces
 */
static char *get_body(xml_node_t *node)
{
	char *s1, *s2;

	if (!node)
		return NULL;
	if (!(s1 = node->pszBody))
		return NULL;
	for (; *s1 == ' '; s1++);
	for (s2 = s1 + strlen(s1); (s2 > s1) && (*(s2-1) == ' '); s2--);
	if (*s2 == ' ')
		*s2 = '\0';
	return s1;
}


void printTree(xml_node_t *root)
{
	xml_node_t *cur = root;
	while(cur != NULL){
		int i;
		printf(" - %s\n",cur->pszTag);
                for(i = 0;i < cur->iNumAttr;i++){
                        printf("     %s = %s\n",cur->ppszAttrName[i], cur->ppszAttrValue[i]);
		}
		cur = get_next_sibling(cur);
	}	
}
/*
 * Input: Pointer 'eServer_ipl_script' to the root node of the parse tree.
 *
 */

int get_fcp_info (char* ldipl_xml, fcp_info_t* fcp_info) 
{
	int         rc = 0;
	xml_node_t  *act_node,*tmp_node;
	xml_node_t  *eServer_ipl_script;
	xml_doc_t   *xmlDoc = NULL;

        /* call XML parser */
        PRINT_TRACE("starting XML parser...\n");
        if(xml_parse(ldipl_xml, &xmlDoc) != 0){
                PRINT_TRACE("XML parser returned with error code:  %d,\n"
                         "Please check your XML data.\n", rc);
		rc = -1; goto out;
        }
 
        PRINT_TRACE("XML-file encoding: %s\n", xmlDoc->pszXmlEncoding);
        PRINT_TRACE("XML-file version : %s\n", xmlDoc->pszXmlVersion);
        PRINT_TRACE("XML-file doctype : %s\n", xmlDoc->pszDocType);


	eServer_ipl_script = xmlDoc->pxnRoot;

	if (!eServer_ipl_script){
		printf("No <eServer_ipl_script> found.\n");
		rc = -1; goto out;
	}
	fcp_info->type = get_body(get_child(eServer_ipl_script, XML_TAGTYPE_type));
	act_node = get_child(eServer_ipl_script, XML_TAGTYPE_ipl_control_section);
	if(!act_node){
		printf("No IPL control section\n");
		rc = -1; goto out;
	}
	act_node = get_child(act_node, XML_TAGTYPE_ipl_platform_loader);
	if(!act_node){
		printf("No ipl_platform_loader section\n");
		rc = -1; goto out;
	}
	act_node = get_child(act_node, XML_TAGTYPE_fcp_ipl);
	if(!act_node){
		printf("No fcp ipl section\n");
		rc = -1; goto out;
	}
	tmp_node = get_child(act_node, XML_TAGTYPE_devno);
	if(tmp_node)
		fcp_info->devno    = strtol(get_body(tmp_node),NULL,16);
	tmp_node = get_child(act_node, XML_TAGTYPE_wwpn);
	if(tmp_node)
		fcp_info->wwpn     = strtoll(get_body(tmp_node),NULL,16);
	tmp_node = get_child(act_node, XML_TAGTYPE_fcp_lun);
	if(tmp_node)
		fcp_info->fcp_lun  = strtoll(get_body(tmp_node),NULL,16);
	tmp_node = get_child(act_node, XML_TAGTYPE_configuration);
	if(tmp_node)
		fcp_info->configuration= atoi(get_body(tmp_node));
out:
	return rc;
}
