/**
 * 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
 *
 * DSIGTransformC14n := Class that performs C14n canonicalisation
 *
 * $Id$
 *
 */

#include <xsec/dsig/DSIGTransformC14n.hpp>
#include <xsec/framework/XSECException.hpp>
#include <xsec/transformers/TXFMC14n.hpp>
#include <xsec/transformers/TXFMChain.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/framework/XSECEnv.hpp>
#include <xsec/dsig/DSIGSignature.hpp>

#include <xercesc/util/Janitor.hpp>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Constructors and Destructors
// --------------------------------------------------------------------------------

DSIGTransformC14n::DSIGTransformC14n(const XSECEnv * env, DOMNode * node) :
DSIGTransform(env, node) {

	m_cMethod = CANON_NONE;
	mp_inclNSNode = NULL;
	mp_inclNSStr = NULL;
}


DSIGTransformC14n::DSIGTransformC14n(const XSECEnv * env) :
DSIGTransform(env) {

	m_cMethod = CANON_NONE;
	mp_inclNSNode = NULL;
	mp_inclNSStr = NULL;

}

DSIGTransformC14n::~DSIGTransformC14n() {};

// --------------------------------------------------------------------------------
//           Interface Methods
// --------------------------------------------------------------------------------

transformType DSIGTransformC14n::getTransformType() {

	if ((m_cMethod == CANON_C14NE_NOC) || (m_cMethod == CANON_C14NE_COM))
		return TRANSFORM_EXC_C14N;
	else if ((m_cMethod == CANON_C14N11_NOC) || (m_cMethod == CANON_C14N11_COM))
        return TRANSFORM_C14N11;
	return TRANSFORM_C14N;

}

void DSIGTransformC14n::appendTransformer(TXFMChain * input) {

	TXFMC14n * c;

	XSECnew(c, TXFMC14n(mp_txfmNode->getOwnerDocument()));
	input->appendTxfm(c);

	switch (m_cMethod) {

	case (CANON_C14N_NOC) :
	case (CANON_C14N11_NOC) :
	case (CANON_C14NE_NOC) :
		c->stripComments();
		break;
	case (CANON_C14N_COM) :
    case (CANON_C14N11_COM) :
	case (CANON_C14NE_COM) :
		c->activateComments();
		break;
	default:
		break;
	}

	// Check for exclusive and 1.1
	if (m_cMethod == CANON_C14NE_COM || m_cMethod == CANON_C14NE_NOC) {

		if (mp_inclNSStr == NULL) {

			c->setExclusive();

		}
		else {

			safeBuffer incl;
			incl << (*(mp_env->getSBFormatter()) << mp_inclNSStr);
			c->setExclusive(incl);

		}

	}
	else if (m_cMethod == CANON_C14N11_COM || m_cMethod == CANON_C14N11_NOC) {
	    c->setInclusive11();
	}

}

DOMElement * DSIGTransformC14n::createBlankTransform(DOMDocument * parentDoc) {

	safeBuffer str;
	const XMLCh * prefix;
	DOMElement *ret;
	DOMDocument *doc = mp_env->getParentDocument();

	prefix = mp_env->getDSIGNSPrefix();

	// Create the transform node
	makeQName(str, prefix, "Transform");
	ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
	ret->setAttributeNS(NULL,DSIGConstants::s_unicodeStrAlgorithm, DSIGConstants::s_unicodeStrURIC14N_NOC);

	mp_txfmNode = ret;
	mp_inclNSStr = NULL;
	mp_inclNSNode = NULL;

	return ret;

}

void DSIGTransformC14n::load(void) {

	const XMLCh * uri;
	DOMNamedNodeMap * atts;
	DOMNode *att;

	// Read the URI for the type
	if (mp_txfmNode == NULL) {

		throw XSECException(XSECException::ExpectedDSIGChildNotFound,
			"Expected <Transform> Node in DSIGTrasnformC14n::load");

	}

	atts = mp_txfmNode->getAttributes();

	if (atts == NULL ||
		((att = atts->getNamedItem(DSIGConstants::s_unicodeStrAlgorithm)) == NULL)) {

		throw XSECException(XSECException::ExpectedDSIGChildNotFound,
			"Expected to find Algorithm attribute in <Transform> node");

	}

	uri = att->getNodeValue();

	if (strEquals(uri, DSIGConstants::s_unicodeStrURIC14N_COM)) {
		m_cMethod = CANON_C14N_COM;
	}
	else if (strEquals(uri, DSIGConstants::s_unicodeStrURIC14N_NOC)) {
		m_cMethod = CANON_C14N_NOC;
	}
	else if (strEquals(uri, DSIGConstants::s_unicodeStrURIC14N11_COM)) {
        m_cMethod = CANON_C14N11_COM;
    }
    else if (strEquals(uri, DSIGConstants::s_unicodeStrURIC14N11_NOC)) {
        m_cMethod = CANON_C14N11_NOC;
    }
	else if (strEquals(uri, DSIGConstants::s_unicodeStrURIEXC_C14N_COM)) {
		m_cMethod = CANON_C14NE_COM;
	}
	else if (strEquals(uri, DSIGConstants::s_unicodeStrURIEXC_C14N_NOC)) {
		m_cMethod = CANON_C14NE_NOC;
	}
	else {
		throw XSECException(XSECException::ExpectedDSIGChildNotFound,
			"Unexpected URI found in canonicalisation <Transform>");
	}

	// Determine whether there is an InclusiveNamespaces list

	if (m_cMethod == CANON_C14NE_NOC || m_cMethod == CANON_C14NE_COM) {

		// Exclusive, so there may be an InclusiveNamespaces node

		DOMNode * inclNSNode = mp_txfmNode->getFirstChild();

		while (inclNSNode != NULL && (inclNSNode->getNodeType() != DOMNode::ELEMENT_NODE ||
			!strEquals(getECLocalName(inclNSNode), "InclusiveNamespaces")))
				inclNSNode = inclNSNode->getNextSibling();

		if (inclNSNode != 0) {

			mp_inclNSNode = static_cast<DOMElement *>(inclNSNode);

			// Have a prefix list
			atts = mp_inclNSNode->getAttributes();
			safeBuffer inSB;

			if (atts == 0 || ((att = atts->getNamedItem(MAKE_UNICODE_STRING("PrefixList"))) == NULL)) {
				throw XSECException(XSECException::ExpectedDSIGChildNotFound,
					"Expected PrefixList in InclusiveNamespaces");
			}

			mp_inclNSStr = att->getNodeValue();

		}
	}

}

// --------------------------------------------------------------------------------
//           Canonicalization Specific Methods
// --------------------------------------------------------------------------------


void DSIGTransformC14n::setCanonicalizationMethod(canonicalizationMethod method) {

	const XMLCh * m = canonicalizationMethod2UNICODEURI(method);

	if (strEquals(m, DSIGConstants::s_unicodeStrEmpty) || mp_txfmNode == NULL) {

		throw XSECException(XSECException::TransformError,
			"Either method unknown or Node not set in setCanonicalizationMethod");

	}

	if (method == CANON_C14N_NOC || method == CANON_C14N_COM || method == CANON_C14N11_NOC || method == CANON_C14N11_COM) {

		if (m_cMethod == CANON_C14NE_NOC || m_cMethod == CANON_C14NE_COM) {

			if (mp_inclNSNode != 0) {

				mp_txfmNode->removeChild(mp_inclNSNode);
				mp_inclNSNode->release();		// No longer required

				mp_inclNSNode = NULL;
				mp_inclNSStr = NULL;

			}
		}

	}

	// Now do the set.

	((DOMElement *) mp_txfmNode)->setAttributeNS(NULL,MAKE_UNICODE_STRING("Algorithm"), m);
	m_cMethod = method;

}

canonicalizationMethod DSIGTransformC14n::getCanonicalizationMethod(void) {

	return m_cMethod;

}

void DSIGTransformC14n::createInclusiveNamespaceNode(void) {

	// Creates an empty inclusiveNamespace node.  Does _not_ set the prefixlist attribute

	if (mp_inclNSNode != NULL)
		return;		// Already exists

	safeBuffer str;
	const XMLCh * prefix;
	DOMDocument *doc = mp_env->getParentDocument();

	// Use the Exclusive Canonicalisation prefix
	prefix = mp_env->getECNSPrefix();

	// Create the transform node
	makeQName(str, prefix, "InclusiveNamespaces");
	mp_inclNSNode = doc->createElementNS(DSIGConstants::s_unicodeStrURIEC, str.rawXMLChBuffer());

	// Add the node to the owner element
	mp_env->doPrettyPrint(mp_txfmNode);
	mp_txfmNode->appendChild(mp_inclNSNode);
	mp_env->doPrettyPrint(mp_txfmNode);

	// Set the namespace attribute
	if (prefix[0] == '\0') {
		str.sbTranscodeIn("xmlns");
	}
	else {
		str.sbTranscodeIn("xmlns:");
		str.sbXMLChCat(prefix);
	}

	mp_inclNSNode->setAttributeNS(DSIGConstants::s_unicodeStrURIXMLNS,
							str.rawXMLChBuffer(),
							DSIGConstants::s_unicodeStrURIEC);
}

void DSIGTransformC14n::setInclusiveNamespaces(const XMLCh * ns) {

	// Set all the namespaces at once

	if (m_cMethod != CANON_C14NE_COM && m_cMethod != CANON_C14NE_NOC) {

		throw XSECException(XSECException::TransformError,
			"Cannot set inclusive namespaces on non Exclusive Canonicalisation");

	}

	if (mp_inclNSNode == NULL) {

		// Create the transform node
		createInclusiveNamespaceNode();


	}

	// Now create the prefix list

	mp_inclNSNode->setAttributeNS(NULL,MAKE_UNICODE_STRING("PrefixList"), ns);
	mp_inclNSStr = mp_inclNSNode->getAttributes()->getNamedItem(MAKE_UNICODE_STRING("PrefixList"))->getNodeValue();

}


void DSIGTransformC14n::addInclusiveNamespace(const char * ns) {

	if (m_cMethod != CANON_C14NE_COM && m_cMethod != CANON_C14NE_NOC) {

		throw XSECException(XSECException::TransformError,
			"Cannot set inclusive namespaces on non Exclusive Canonicalisation");

	}

	if (mp_inclNSNode == NULL) {

		// Create the transform node
		createInclusiveNamespaceNode();

		// Now create the prefix list

		mp_inclNSNode->setAttributeNS(NULL,MAKE_UNICODE_STRING("PrefixList"), MAKE_UNICODE_STRING(ns));
		mp_inclNSStr = mp_inclNSNode->getAttributes()->getNamedItem(MAKE_UNICODE_STRING("PrefixList"))->getNodeValue();

	}

	else {

		// More tricky
		safeBuffer str;

		str << (*(mp_env->getSBFormatter()) << mp_inclNSStr);
		str.sbStrcatIn(" ");
		str.sbStrcatIn((char *) ns);
		mp_inclNSNode->setAttributeNS(NULL,MAKE_UNICODE_STRING("PrefixList"), str.sbStrToXMLCh());
		mp_inclNSStr = mp_inclNSNode->getAttributes()->getNamedItem(MAKE_UNICODE_STRING("PrefixList"))->getNodeValue();

	}

}

const XMLCh * DSIGTransformC14n::getPrefixList(void) {

	return mp_inclNSStr;

}

void DSIGTransformC14n::clearInclusiveNamespaces(void) {

	if (mp_inclNSNode != 0) {

		mp_txfmNode->removeChild(mp_inclNSNode);
		mp_inclNSNode->release();		// No longer required

		mp_inclNSNode = NULL;
		mp_inclNSStr = NULL;

	}
}
