#include <Include/PlatformDefinitions.hpp>
#include <parsers/DOMParser.hpp>
#include <stdlib.h>
#include <pthread.h>
#include <cassert>
#include <stdio.h>
#if defined(XALAN_OLD_STREAM_HEADERS)
    #include <iostream.h>
#else
    #include <iostream>
#endif

#include <util/PlatformUtils.hpp>
#include <framework/LocalFileInputSource.hpp>

#include <XalanDOM/XalanDocument.hpp>
#include <XalanDOM/XalanElement.hpp>

#include <XPath/XObject.hpp>
#include <XPath/XPathEvaluator.hpp>

#include <XalanSourceTree/XalanSourceTreeDOMSupport.hpp>
#include <XalanSourceTree/XalanSourceTreeInit.hpp>
#include <XalanSourceTree/XalanSourceTreeParserLiaison.hpp>

#include <framework/MemBufInputSource.hpp>
#include <sax/InputSource.hpp>

/**********************************************************************/
// 	This is a single function API for traversing an input xml string
// 	evaluating an XPath over the same. The function to be used is :
//
//	getValue(char* eventStr, char* eventRoot,char* xpath)
//	
//	where
//	eventStr       : The XML Event required to be processed.
//
//	eventRoot      : The Root node of the xml string.
//
//	xpath          : The xpath to be evaluated on the given event.
//
//	IMPORTANT : Only simple xpath expressions are supported.
/**********************************************************************/

static const char* gMemBufId = "xEvent";
extern "C" char*  getValue(char* eventStr,char* eventRoot,char* xpath) 
{
    #if !defined(XALAN_NO_NAMESPACES)
	using std::cerr;
	using std::cout;
	using std::endl;
    #endif

    // Check if eventStr or xpath are NULL or empty
    if ((eventStr == NULL) || (eventStr == "") || 
                                      (xpath == NULL) || (xpath == ""))
        cout << "EXCEPTION!!! --- EVENT STRING NULL or empty .... Exiting...";
    else {
	try {
                {
                    // Initialize the XalanSourceTree subsystem...
                    XalanSourceTreeInit		theSourceTreeInit;
                    // We'll use these to parse the XML String.
                    XalanSourceTreeDOMSupport		theDOMSupport;
                    XalanSourceTreeParserLiaison	theLiaison(theDOMSupport);


  	// Hook the two together...
				theDOMSupport.setParserLiaison(&theLiaison);

				// Create an Input source that represents a char string 	:pn
				MemBufInputSource* memBufIS = new MemBufInputSource((const XMLByte*)eventStr, strlen(eventStr), gMemBufId, false);

				    
				// Parse the document...
				XalanDocument *theDocument = theLiaison.parseXMLStream(*memBufIS);
				assert(theDocument != 0);
				
				XPathEvaluator	theEvaluator;
        
				
        // OK, let's find the context node...
				XalanNode* const theContextNode = theEvaluator.selectSingleNode(
							theDOMSupport,
							theDocument,
							XalanDOMString(eventRoot).c_str(),
							0);

				if (theContextNode == 0)
				{
					cerr << "Warning -- No nodes matched the location path \""
						 << "event"
						 << "\"."
						 << endl
						 << "Execution cannot continue..."
						 << endl
						 << endl;
				}
				else
				{
					// OK, let's evaluate the expression...
					XObjectPtr theResult( theEvaluator.evaluate(
								theDOMSupport,
								theContextNode,
								XalanDOMString(xpath).c_str(),
								0));

					assert(theResult.null() == false);

                                        XalanDOMString str =  theResult->str();

					// Extract the result from XalanDOMString	:hv
					int size = str.size();
          char *resultStr = (char*)malloc((size+1)*sizeof(char)); // DO Remeber to dealloc this after the call

					if (resultStr)
					{       
 						int i = 0;
						for ( ; i < size ; i++)
							resultStr[i] = str[i];
						
						resultStr[i] = '\0';

            /* DEC 19 added to free ....*/
            delete memBufIS;

						return resultStr;
					}
				}
        /* DEC 19 added to free ....*/
        delete memBufIS;
			}

		}
		catch(...)
		{
			cerr << "Exception caught!" << endl;
			return "EXCEPTION IN XML DECODING !!!! Exciting...";
		}
	return "XML Decoding NOT DONE...Check for errors !!! Exciting...";
	}
}

//_______________________________________________________________________
//TEST MAIN FUNCTION for independent testing 		
//_______________________________________________________________________

void *Run(void *p) {

char* eventStr = "<event>
        <payload>
                <sendSMS state='request'>
                        <gateway name='ESCOTEL' userID='ispl' userPwd='ispl' port='80'/>
                        <message ID='993984875837' subID='' text='Hi this is thefirst test message from SMSx' destinationNo='91981011' gwRespFlag='0'/>
                </sendSMS>
                <test>1</test>
                <sendSMS state='confirm'>
                        <gateway name='AIRTEL' port='777'>
                                <test>2</test>
                        </gateway>
                </sendSMS>
        </payload>
</event >";
XMLPlatformUtils::Initialize();
XPathEvaluator::initialize();
int cont = 1;
for(int i = 0; i < 10000; i++) {
    char* value = getValue(eventStr, "event", "/event/payload/sendSMS/gateway/@name");
    char* value1 = getValue(eventStr, "event", "/event/payload/sendSMS/gateway/@userID");
    char* value2 = getValue(eventStr, "event", "/event/payload/sendSMS/gateway/@userPwd");
    char* value3 = getValue(eventStr, "event", "/event/payload/sendSMS/gateway/@port");
    char* value4 = getValue(eventStr, "event", "/event/payload/sendSMS/message/@ID");
    char* value5 = getValue(eventStr, "event", "/event/payload/sendSMS/message/@subID");
    cout <<"The result is --------\n THREAD" << value << "\n\n";
    cout <<"The result is --------\n THREAD" << value1 << "\n\n";
    cout <<"The result is --------\n THREAD" << value2 << "\n\n";
    cout <<"The result is --------\n THREAD" << value3 << "\n\n";
    cout <<"The result is --------\n THREAD" << value4 << "\n\n";
    cout <<"The result is --------\n THREAD" << value5 << "\n\n";
    free(value);
    free(value1);
    free(value2);
    free(value3);
    free(value4);
    free(value5);
//	XPathEvaluator::terminate();
//	XMLPlatformUtils::Terminate();
}
    return (void *)&cont;
}

void main(int argc, char* argv[]){
pthread_t temp;
int p;
char* eventStr = "<event>
        <payload>
                <send SMS state='request'>
                        <gateway name='ESCOTEL' userID='ispl' userPwd='ispl' port='80'/>
                        <message ID='993984875837' subID='' text='Hi this is thefirst test message from SMSx' destinationNo='91981011' gwRespFlag='0'/>
                </sendSMS>
                <test>1</test>
                <sendSMS state='confirm'>
                        <gateway name='AIRTEL' port='777'>
                                <test>2</test>
                        </gateway>
                </sendSMS>
        </payload>
</event >";
XMLPlatformUtils::Initialize();
XPathEvaluator::initialize();
int cont = 1;
//while (cont) {
    char* value = getValue(eventStr, "event", "/event/payload/sendSMS/gateway/@name");
    char* value1 = getValue(eventStr, "event", "/event/payload/sendSMS/gateway/@userID");
    char* value2 = getValue(eventStr, "event", "/event/payload/sendSMS/gateway/@userPwd");
    char* value3 = getValue(eventStr, "event", "/event/payload/sendSMS/gateway/@port");
    char* value4 = getValue(eventStr, "event", "/event/payload/sendSMS/message/@ID");
    char* value5 = getValue(eventStr, "event", "/event/payload/sendSMS/message/@subID");
    cout <<"The result is --------\n" << value << "\n\n";
    cout <<"The result is --------\n" << value1 << "\n\n";
    cout <<"The result is --------\n" << value2 << "\n\n";
    cout <<"The result is --------\n" << value3 << "\n\n";
    cout <<"The result is --------\n" << value4 << "\n\n";
    cout <<"The result is --------\n" << value5 << "\n\n";
    free(value);
    free(value1);
    free(value2);
    free(value3);
    free(value4);
    free(value5);
	XPathEvaluator::terminate();
	XMLPlatformUtils::Terminate();
}

//______________________________________________________________________
#undef USE_GWMEM_CHECK

