/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*
 * XSEC
 *
 * TXFMXSL := Class that performs XPath transforms
 *
 * $Id$
 *
 */

#include <xsec/transformers/TXFMXSL.hpp>
#include <xsec/dsig/DSIGConstants.hpp>
#include <xsec/framework/XSECError.hpp>

#ifndef XSEC_NO_XSLT

// Xerces
#include <xercesc/dom/DOM.hpp>
#include <xercesc/dom/DOMImplementation.hpp>
#include <xercesc/dom/DOMImplementationLS.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/framework/MemBufInputSource.hpp>
#include <xercesc/util/Janitor.hpp>

XERCES_CPP_NAMESPACE_USE

#include <iostream>
#include <strstream>
#include <fstream>

XALAN_USING_XALAN(XSLTResultTarget)

// Function used to output data to a safeBuffer
extern "C" {

typedef struct TransformXSLOutputHolderStruct {

	safeBuffer	buffer;
	int			offset;

} TransformXSLOutputHolder;

CallbackSizeType TransformXSLOutputFn(const char * s, CallbackSizeType sz, void * data) {

	TransformXSLOutputHolder * output = (TransformXSLOutputHolder *) data;

	output->buffer.sbMemcpyIn(output->offset, s, (int) sz);
	output->offset += (int) sz;
	output->buffer[output->offset] = '\0';

	return sz;

}
}

// -----------------------------------------------------------------------
//  For expanding name spaces when necessary
// -----------------------------------------------------------------------

bool TXFMXSL::nameSpacesExpanded(void) {

	// NOTE : Do not check inputs as this has its own document

	return (mp_nse != NULL);

}

void TXFMXSL::expandNameSpaces(void) {

	if (mp_nse != NULL)
		return;		// Already done
	
	if (docOut != NULL) {

		XSECnew(mp_nse, XSECNameSpaceExpander(docOut));

		mp_nse->expandNameSpaces();

	}

}

// -----------------------------------------------------------------------
//  Transform functions
// -----------------------------------------------------------------------


TXFMXSL::TXFMXSL(DOMDocument *doc) : 
	TXFMBase(doc),
#if XALAN_VERSION_MAJOR == 1 && XALAN_VERSION_MINOR > 10
xds(xpl)
#else
#if defined XSEC_XERCESPARSERLIAISON_REQS_DOMSUPPORT
xpl(xds) 
#else
xpl()
#endif
#endif
{

	// Zeroise all the pointers

	xd = NULL;

}

TXFMXSL::~TXFMXSL() {

	if (docOut != NULL) {
		if (mp_nse != NULL) {
			delete mp_nse;	// Don't bother collapsing
			mp_nse = NULL;
		}
		docOut->release();	
	}
}

// Methods to set the inputs

void TXFMXSL::setInput(TXFMBase *newInput) {

	input = newInput;

	if (newInput->getOutputType() != TXFMBase::BYTE_STREAM) {

		throw XSECException(XSECException::TransformInputOutputFail, "XSL requires DOM_NODES input type");

	}

	// Should have a method to check if the input is a straight URL - if it is, just read the
	// URL name and create an XSLTInputSource with this as the input ID.

	int size = 0;
	int count = 0;
	unsigned char buf[512];

	while ((count = input->readBytes((XMLByte *) buf, 512)) != 0) {

		sbInDoc.sbMemcpyIn(size, buf, count);
		size += count;

	}

	sbInDoc[size] = '\0';

}

void TXFMXSL::evaluateStyleSheet(const safeBuffer &sbStyleSheet) {

	// Set up iostreams for input
	std::istrstream	theXMLStream((char *) sbInDoc.rawBuffer(), (int) strlen((char *) sbInDoc.rawBuffer()));
	std::istrstream	theXSLStream((char *) sbStyleSheet.rawBuffer(), (int) strlen((char *) sbStyleSheet.rawBuffer()));

	// Now resolve

	XalanTransformer xt;
	TransformXSLOutputHolder txoh;
	txoh.buffer.sbStrcpyIn("");
	txoh.offset = 0;
	
	/*int res = */
	xt.transform(&theXMLStream, &theXSLStream, (void *) & txoh, TransformXSLOutputFn);

	// Should check res

	// Now use xerces to "re parse" this back into a DOM_Nodes document
	XercesDOMParser * parser = new XercesDOMParser;
	Janitor<XercesDOMParser> j_parser(parser);

	parser->setDoNamespaces(true);
	parser->setCreateEntityReferenceNodes(true);
	parser->setLoadExternalDTD(false);
	parser->setDoSchema(true);

	SecurityManager securityManager;
	parser->setSecurityManager(&securityManager);

	// Create an input source

	MemBufInputSource* memIS = new MemBufInputSource ((const XMLByte*) txoh.buffer.rawBuffer(), txoh.offset, "XSECMem");
	Janitor<MemBufInputSource> j_memIS(memIS);

	int errorCount = 0;

	parser->parse(*memIS);
    errorCount = parser->getErrorCount();
    if (errorCount > 0)
		throw XSECException(XSECException::XSLError, "Errors occured when XSL result was parsed back to DOM_Nodes");

    docOut = parser->adoptDocument();

	// Janitors clean up

}

// Methods to get tranform output type and input requirement

TXFMBase::ioType TXFMXSL::getInputType(void) {

	return TXFMBase::DOM_NODES;

}
TXFMBase::ioType TXFMXSL::getOutputType(void) {

	return TXFMBase::DOM_NODES;

}

TXFMBase::nodeType TXFMXSL::getNodeType(void) {

	return TXFMBase::DOM_NODE_DOCUMENT;

}

// Methods to get output data

unsigned int TXFMXSL::readBytes(XMLByte * const toFill, unsigned int maxToFill) {

	return 0;

}

DOMDocument * TXFMXSL::getDocument() {

	return docOut;

}

DOMNode * TXFMXSL::getFragmentNode() {

	return NULL;

}

const XMLCh * TXFMXSL::getFragmentId() {

	return NULL;	// Empty string

}

#endif /* NO_XSLT */
