/**
 * 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
 *
 * XSECDOMUtils:= Utilities to manipulate DOM within XML-SECURITY
 *
 * $Id$
 *
 */

// XSEC

#include <xsec/utils/XSECDOMUtils.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/xkms/XKMSConstants.hpp>

// Xerces

#include <xercesc/util/XMLUniDefs.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/util/TransService.hpp>

#include <string.h>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Utilities to manipulate DSIG namespaces
// --------------------------------------------------------------------------------

const XMLCh * getDSIGLocalName(const DOMNode *node) {

	if (!strEquals(node->getNamespaceURI(), DSIGConstants::s_unicodeStrURIDSIG))
		return NULL; //DOMString("");
	else
		return node->getLocalName();

}

const XMLCh * getDSIG11LocalName(const DOMNode *node) {

	if (!strEquals(node->getNamespaceURI(), DSIGConstants::s_unicodeStrURIDSIG11))
		return NULL; //DOMString("");
	else
		return node->getLocalName();

}

const XMLCh * getECLocalName(const DOMNode * node) {

	// Exclusive Canonicalisation namespace
	// Probably should have a generic function

	if (!strEquals(node->getNamespaceURI(), DSIGConstants::s_unicodeStrURIEC))
		return NULL;
	else
		return node->getLocalName();

}

const XMLCh * getXPFLocalName(const DOMNode * node) {

	// XPath Filter namespace

	if (!strEquals(node->getNamespaceURI(), DSIGConstants::s_unicodeStrURIXPF))
		return NULL;
	else
		return node->getLocalName();

}

const XMLCh * getXENCLocalName(const DOMNode *node) {

	// XML Encryption namespace node

	if (!strEquals(node->getNamespaceURI(), DSIGConstants::s_unicodeStrURIXENC))
		return NULL;
	else
		return node->getLocalName();

}

const XMLCh * getXENC11LocalName(const DOMNode *node) {

	// XML Encryption 1.1 namespace node

	if (!strEquals(node->getNamespaceURI(), DSIGConstants::s_unicodeStrURIXENC11))
		return NULL;
	else
		return node->getLocalName();

}

#ifdef XSEC_XKMS_ENABLED
const XMLCh * getXKMSLocalName(const DOMNode *node) {

	// XKMS namespace node

	if (!strEquals(node->getNamespaceURI(), XKMSConstants::s_unicodeStrURIXKMS))
		return NULL;
	else
		return node->getLocalName();

}
#endif

// --------------------------------------------------------------------------------
//           Find a nominated DSIG node in a document
// --------------------------------------------------------------------------------

DOMNode *findDSIGNode(DOMNode *n, const char * nodeName) {

	const XMLCh * name = getDSIGLocalName(n);

	if (strEquals(name, nodeName)) {

		return n;

	}

	DOMNode *child = n->getFirstChild();

	while (child != NULL) {

		DOMNode *ret = findDSIGNode(child, nodeName);
		if (ret != NULL)
			return ret;
		child = child->getNextSibling();

	}

	return child;

}

// --------------------------------------------------------------------------------
//           Find a nominated XENC node in a document
// --------------------------------------------------------------------------------

DOMNode *findXENCNode(DOMNode *n, const char * nodeName) {

	const XMLCh * name = getXENCLocalName(n);

	if (strEquals(name, nodeName)) {

		return n;

	}

	DOMNode *child = n->getFirstChild();

	while (child != NULL) {

		DOMNode *ret = findXENCNode(child, nodeName);
		if (ret != NULL)
			return ret;
		child = child->getNextSibling();

	}

	return child;

}

// --------------------------------------------------------------------------------
//           Find particular type of node child
// --------------------------------------------------------------------------------

DOMNode *findFirstChildOfType(DOMNode *n, DOMNode::NodeType t) {

	DOMNode *c;

	if (n == NULL)
		return n;

	c = n->getFirstChild();

	while (c != NULL && c->getNodeType() != t)
		c = c->getNextSibling();

	return c;

}

DOMNode * findNextChildOfType(DOMNode *n, DOMNode::NodeType t) {

	DOMNode * s = n;

	if (s == NULL)
		return s;

	do {
		s = s->getNextSibling();
	} while (s != NULL && s->getNodeType() != t);

	return s;

}

DOMElement *findFirstElementChild(DOMNode *n) {

	DOMNode *c;

	if (n == NULL)
		return NULL;

	c = n->getFirstChild();

	while (c != NULL && c->getNodeType() != DOMNode::ELEMENT_NODE)
		c = c->getNextSibling();

	return (DOMElement *) c;

}

DOMElement * findNextElementChild(DOMNode *n) {

	DOMNode * s = n;

	if (s == NULL)
		return NULL;

	do {
		s = s->getNextSibling();
	} while (s != NULL && s->getNodeType() != DOMNode::ELEMENT_NODE);

	return (DOMElement *) s;

}

// --------------------------------------------------------------------------------
//           Make a QName
// --------------------------------------------------------------------------------

safeBuffer &makeQName(safeBuffer & qname, safeBuffer &prefix, const char * localName) {

	if (prefix[0] == '\0') {
		qname = localName;
	}
	else {
		qname = prefix;
		qname.sbStrcatIn(":");
		qname.sbStrcatIn(localName);
	}

	return qname;

}
safeBuffer &makeQName(safeBuffer & qname, const XMLCh *prefix, const char * localName) {

	if (prefix == NULL || prefix[0] == 0) {
		qname.sbTranscodeIn(localName);
	}
	else {
		qname.sbXMLChIn(prefix);
		qname.sbXMLChAppendCh(XERCES_CPP_NAMESPACE_QUALIFIER chColon);
		qname.sbXMLChCat(localName);	// Will transcode
	}

	return qname;
}

safeBuffer &makeQName(safeBuffer & qname, const XMLCh *prefix, const XMLCh * localName) {

	if (prefix == NULL || prefix[0] == 0) {
		qname.sbXMLChIn(localName);
	}
	else {
		qname.sbXMLChIn(prefix);
		qname.sbXMLChAppendCh(XERCES_CPP_NAMESPACE_QUALIFIER chColon);
		qname.sbXMLChCat(localName);
	}

	return qname;
}

// --------------------------------------------------------------------------------
//           "Quick" Transcode (low performance)
// --------------------------------------------------------------------------------



XMLT::XMLT(const char * str) {

	mp_unicodeStr = XMLString::transcode(str);

}

XMLT::~XMLT (void) {

	XSEC_RELEASE_XMLCH(mp_unicodeStr);

}

XMLCh * XMLT::getUnicodeStr(void) {

	return mp_unicodeStr;

}

// --------------------------------------------------------------------------------
//           Gather text from children
// --------------------------------------------------------------------------------

void gatherChildrenText(DOMNode * parent, safeBuffer &output) {

	DOMNode * c = parent->getFirstChild();

	output.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);

	while (c != NULL) {

		if (c->getNodeType() == DOMNode::TEXT_NODE)
			output.sbXMLChCat(c->getNodeValue());

		c = c->getNextSibling();

	}

}

// --------------------------------------------------------------------------------
//           Some UTF8 utilities
// --------------------------------------------------------------------------------

XMLCh * transcodeFromUTF8(const unsigned char * src) {

	// Take a UTF-8 buffer and transcode to UTF-16

	safeBuffer fullDest;
	fullDest.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);
	XMLCh outputBuf[2050];

	// Used to record byte sizes
	unsigned char charSizes[2050];

	// Grab a transcoder
	XMLTransService::Codes failReason;

	XMLTranscoder* t =
		XMLPlatformUtils::fgTransService->makeNewTranscoderFor("UTF-8",
					   failReason,
					   2*1024,
					   XMLPlatformUtils::fgMemoryManager);
	Janitor<XMLTranscoder> j_t(t);

	// Need to loop through, 2K at a time
	XMLSize_t bytesEaten, bytesEatenCounter;
	XMLSize_t charactersEaten;
	XMLSize_t totalBytesEaten = 0;
	XMLSize_t bytesToEat = XMLString::stringLen((char *) src);

	while (totalBytesEaten < bytesToEat) {

	    XMLSize_t toEat = bytesToEat - totalBytesEaten;


		if (toEat > 2048)
			toEat = 2048;

		t->transcodeFrom(&src[totalBytesEaten],
						toEat,
						outputBuf,
						2048,
						bytesEaten,
						charSizes);

		// Determine how many characters were used
		bytesEatenCounter = 0;
		charactersEaten = 0;
		while (bytesEatenCounter < bytesEaten) {
			bytesEatenCounter += charSizes[charactersEaten++];
		}

		outputBuf[charactersEaten] = chNull;
		fullDest.sbXMLChCat(outputBuf);
		totalBytesEaten += bytesEaten;
	}

	// Dup and output
	return XMLString::replicate(fullDest.rawXMLChBuffer());

}

char XSEC_EXPORT * transcodeToUTF8(const XMLCh * src) {

	// Take a UTF-16 buffer and transcode to UTF-8

	safeBuffer fullDest("");
	unsigned char outputBuf[2050];

	// Grab a transcoder
	XMLTransService::Codes failReason;

	XMLTranscoder* t =
		XMLPlatformUtils::fgTransService->makeNewTranscoderFor("UTF-8",
						   failReason,
						   2*1024,
						   XMLPlatformUtils::fgMemoryManager);
	Janitor<XMLTranscoder> j_t(t);

	// Need to loop through, 2K at a time
	XMLSize_t charactersEaten, charactersOutput;
	XMLSize_t totalCharsEaten = 0;
	XMLSize_t charsToEat = XMLString::stringLen(src);

	while (totalCharsEaten < charsToEat) {

		XMLSize_t toEat = charsToEat - totalCharsEaten;

		if (toEat > 2048)
			toEat = 2048;

		charactersOutput = t->transcodeTo(&src[totalCharsEaten],
						toEat,
						(unsigned char * const) outputBuf,
						2048,
						charactersEaten,
						XMLTranscoder::UnRep_RepChar);

		outputBuf[charactersOutput] = '\0';
		fullDest.sbStrcatIn((char *) outputBuf);
		totalCharsEaten += charactersEaten;
	}

	// Dup and output
	return XMLString::replicate(fullDest.rawCharBuffer());

}

// --------------------------------------------------------------------------------
//           String decode/encode
// --------------------------------------------------------------------------------

/*
 * Distinguished names have a particular encoding that needs to be performed prior
 * to enclusion in the DOM
 */

XMLCh * encodeDName(const XMLCh * toEncode) {

	XERCES_CPP_NAMESPACE_USE;

	safeBuffer result;

	static XMLCh s_strEncodedSpace[] = {
		chBackSlash,
		chDigit_2,
		chDigit_0,
		chNull
	};

	result.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);

	if (toEncode == NULL) {
		return NULL;
	}


	// Find where the trailing whitespace starts
	const XMLCh * ws = &toEncode[XMLString::stringLen(toEncode)];

	ws--;
	while (ws != toEncode &&
		(*ws == '\t' || *ws == '\r' || *ws ==' ' || *ws == '\n'))
		ws--;

	// Set to first white space character, if we didn't get back to the start
	if (toEncode != ws)
		ws++;

	// Now run through each character and encode if necessary

	const XMLCh * i = toEncode;

	if (*i == chPound) {
		// "#" Characters escaped at the start of a string
		result.sbXMLChAppendCh(chBackSlash);
	}

	while (*i != chNull && i != ws) {

		if (*i <= 0x09) {
			result.sbXMLChAppendCh(chBackSlash);
			result.sbXMLChAppendCh(chDigit_0);
			result.sbXMLChAppendCh(chDigit_0 + *i);
		}
		else if (*i <= 0x0f) {
			result.sbXMLChAppendCh(chBackSlash);
			result.sbXMLChAppendCh(chDigit_0);
			result.sbXMLChAppendCh(chLatin_A + *i);
		}
		else if (*i <= 0x19) {
			result.sbXMLChAppendCh(chBackSlash);
			result.sbXMLChAppendCh(chDigit_1);
			result.sbXMLChAppendCh(chDigit_0 + *i);
		}
		else if (*i <= 0x1f) {
			result.sbXMLChAppendCh(chBackSlash);
			result.sbXMLChAppendCh(chDigit_1);
			result.sbXMLChAppendCh(chLatin_A + *i);
		}

		else if (*i == chComma) {

			// Determine if this is an RDN separator
			const XMLCh *j = i;
			j++;
			while (*j != chComma && *j != chEqual && *j != chNull)
				j++;

			if (*j != chEqual)
				result.sbXMLChAppendCh(chBackSlash);

			result.sbXMLChAppendCh(*i);

		}

		else {

			if (*i == chPlus ||
				*i == chDoubleQuote ||
				*i == chBackSlash ||
				*i == chOpenAngle ||
				*i == chCloseAngle ||
				*i == chSemiColon) {

				result.sbXMLChAppendCh(chBackSlash);
			}

			result.sbXMLChAppendCh(*i);

		}

		i++;

	}

	// Now encode trailing white space
	while (*i != chNull) {

		if (*i == ' ')
			result.sbXMLChCat(s_strEncodedSpace);
		else
			result.sbXMLChAppendCh(*i);

		i++;

	}

	return XMLString::replicate(result.rawXMLChBuffer());

}

XMLCh * decodeDName(const XMLCh * toDecode) {

	// Take an encoded name and decode to a normal XMLCh string

	XERCES_CPP_NAMESPACE_USE;

	safeBuffer result;

	result.sbXMLChIn(DSIGConstants::s_unicodeStrEmpty);

	if (toDecode == NULL) {
		return NULL;
	}

	const XMLCh * i = toDecode;

	if (*i == chBackSlash && i[1] == chPound) {

		result.sbXMLChAppendCh(chPound);
		i++;
		i++;

	}

	while (*i != chNull) {

		if (*i == chBackSlash) {

			i++;

			if (*i == chDigit_0) {

				i++;

				if (*i >= chDigit_0 && *i <= chDigit_9) {
					result.sbXMLChAppendCh(*i - chDigit_0);
				}
				else if (*i >= chLatin_A && *i <= chLatin_F) {
					result.sbXMLChAppendCh(10 + *i - chLatin_A);
				}
				else if (*i >= chLatin_a && *i <= chLatin_f) {
					result.sbXMLChAppendCh(10 + *i - chLatin_a);
				}
				else {
					throw XSECException(XSECException::DNameDecodeError,
						"Unexpected escaped character in Distinguished name");
				}
			}

			else if (*i == chDigit_1) {

				i++;

				if (*i >= chDigit_0 && *i <= chDigit_9) {
					result.sbXMLChAppendCh(16 + *i - chDigit_0);
				}
				else if (*i >= chLatin_A && *i <= chLatin_F) {
					result.sbXMLChAppendCh(26 + *i - chLatin_A);
				}
				else if (*i >= chLatin_a && *i <= chLatin_f) {
					result.sbXMLChAppendCh(26 + *i - chLatin_a);
				}
				else {
					throw XSECException(XSECException::DNameDecodeError,
						"Unexpected escaped character in Distinguished name");
				}
			}

			else if (*i == chDigit_2) {

				i++;

				if (*i == '0') {
					result.sbXMLChAppendCh(' ');
				}

				else {
					throw XSECException(XSECException::DNameDecodeError,
						"Unexpected escaped character in Distinguished name");
				}

			}

			else if (*i == chComma ||
					 *i == chPlus ||
					 *i == chDoubleQuote ||
					 *i == chBackSlash ||
					 *i == chOpenAngle ||
					 *i == chCloseAngle ||
					 *i == chSemiColon) {

				result.sbXMLChAppendCh(*i);
			}

			else {

				throw XSECException(XSECException::DNameDecodeError,
					"Unexpected escaped character in Distinguished name");

			}

			i++;

		}

		else {

			result.sbXMLChAppendCh(*i++);

		}

	}

	return XMLString::replicate(result.rawXMLChBuffer());

}

// --------------------------------------------------------------------------------
//           Misc string functions
// --------------------------------------------------------------------------------

// These three functions are pretty much lifted from XMLURL.cpp in Xerces

static bool isHexDigit(const XMLCh toCheck)
{
    if ((toCheck >= chDigit_0 && toCheck <= chDigit_9)
    ||  (toCheck >= chLatin_A && toCheck <= chLatin_F)
    ||  (toCheck >= chLatin_a && toCheck <= chLatin_f))
    {
        return true;
    }
    return false;
}

static unsigned int xlatHexDigit(const XMLCh toXlat)
{
	if (!isHexDigit(toXlat)) {
		throw XSECException(XSECException::ErrorOpeningURI,
			"Unknown hex char");
	}
    if ((toXlat >= chDigit_0) && (toXlat <= chDigit_9))
        return (unsigned int)(toXlat - chDigit_0);

    if ((toXlat >= chLatin_A) && (toXlat <= chLatin_F))
        return (unsigned int)(toXlat - chLatin_A) + 10;

    return (unsigned int)(toXlat - chLatin_a) + 10;
}

XMLCh * cleanURIEscapes(const XMLCh * uriPath) {

    XMLByte *ptr, *utf8Path;
    XMLSize_t len = XMLString::stringLen(uriPath);

    ptr = utf8Path = new XMLByte[len + 1];

    for (XMLSize_t i = 0; i < len; i++) {
        unsigned int value = uriPath[i];

        if (value > 255) {
            delete[] utf8Path;
            throw XSECException(XSECException::ErrorOpeningURI, "Wide character in URI");
        }

        if (value == chPercent) {
            if (!(i + 2 < len && isHexDigit(uriPath[i + 1]) && isHexDigit(uriPath[i + 2]))) {
                delete[] utf8Path;
                throw XSECException(XSECException::ErrorOpeningURI, "Bad escape sequence in URI");
            }

            value = (xlatHexDigit(uriPath[i + 1]) * 16) + (xlatHexDigit(uriPath[i + 2]));
            i += 2;
        }

        *(ptr++) = (XMLByte) value;
    }
    *ptr = 0;

    try {
        XMLCh* unicodePath = transcodeFromUTF8(utf8Path);
        delete[] utf8Path;
        return unicodePath;
    }
    catch (const XMLException&) {
    }

    delete[] utf8Path;
    throw XSECException(XSECException::ErrorOpeningURI, "Failed to transcode URI from UTF-8");
}

// --------------------------------------------------------------------------------
//           Generate Ids
// --------------------------------------------------------------------------------

void makeHexByte(XMLCh * h, unsigned char b) {

	unsigned char toConvert =  (b & 0xf0);
	toConvert = (toConvert >> 4);

	if (toConvert < 10)
		h[0] = chDigit_0 + toConvert;
	else
		h[0] = chLatin_a + toConvert - 10;

	toConvert =  (b & 0xf);

	if (toConvert < 10)
		h[1] = chDigit_0 + toConvert;
	else
		h[1] = chLatin_a + toConvert - 10;

}


XMLCh * generateId(unsigned int bytes) {

	unsigned char b[128];
	XMLCh id[258];
	unsigned int toGen = (bytes > 128 ? 16 : bytes);

	// Get the appropriate amount of random data
	// Need to zeroise to ensure valgrind is happy
	memset(b, 0, 128);
	memset(id, 0, sizeof(id));
	if (XSECPlatformUtils::g_cryptoProvider->getRandom(b, toGen) != toGen) {

		throw XSECException(XSECException::CryptoProviderError,
			"generateId - could not obtain enough random");

	}

	id[0] = chLatin_I;

	unsigned int i;
	for (i = 0; i < toGen; ++i) {

		makeHexByte(&id[1+(i*2)], b[i]);

	}

	id[1+(i*2)] = chNull;

	return XMLString::replicate(id);

}

