/**
 * 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
 *
 * DSIGKeyName := Simply a string that names a key for an application to read
 *
 * Author(s): Berin Lautenbach
 *
 * $Id$
 *
 */

#include <xsec/dsig/DSIGKeyInfoName.hpp>
#include <xsec/dsig/DSIGSignature.hpp>
#include <xsec/framework/XSECEnv.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/utils/XSECPlatformUtils.hpp>

#include "../utils/XSECDOMUtils.hpp"

XERCES_CPP_NAMESPACE_USE

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


DSIGKeyInfoName::DSIGKeyInfoName(const XSECEnv * env, DOMNode *nameNode) : 
DSIGKeyInfo(env),
mp_name(NULL),
mp_decodedDName(NULL),
mp_keyNameTextNode(0) {

	mp_keyInfoDOMNode = nameNode;

}


DSIGKeyInfoName::DSIGKeyInfoName(const XSECEnv * env) : 
DSIGKeyInfo(env),
mp_name(NULL),
mp_decodedDName(NULL),
mp_keyNameTextNode(0) {

	mp_keyInfoDOMNode = 0;

}


DSIGKeyInfoName::~DSIGKeyInfoName() {

	if (mp_decodedDName != NULL)
		XSEC_RELEASE_XMLCH(mp_decodedDName);

};

// --------------------------------------------------------------------------------
//           Load and Get functions
// --------------------------------------------------------------------------------


void DSIGKeyInfoName::load(void) {

	// Assuming we have a valid DOM_Node to start with, load the signing key so that it can
	// be used later on

	if (mp_keyInfoDOMNode == NULL) {

		// Attempt to load an empty signature element
		throw XSECException(XSECException::LoadEmptyInfoName);

	}

	if (!strEquals(getDSIGLocalName(mp_keyInfoDOMNode), "KeyName")) {

		throw XSECException(XSECException::LoadNonInfoName);

	}

	// Now find the text node containing the name

	DOMNode *tmpElt = mp_keyInfoDOMNode->getFirstChild();

	while (tmpElt != 0 && tmpElt->getNodeType() != DOMNode::TEXT_NODE)
		tmpElt = tmpElt->getNextSibling();

	if (tmpElt != 0) {

		mp_keyNameTextNode = tmpElt;
		mp_name = tmpElt->getNodeValue();

	}

	else {

		throw XSECException(XSECException::ExpectedDSIGChildNotFound,
			MAKE_UNICODE_STRING("Expected TEXT node as child to <KeyName> element"));

	}

}

const XMLCh * DSIGKeyInfoName::getDecodedKeyName(void) {

	if (mp_decodedDName == NULL) {

		mp_decodedDName = decodeDName(mp_name);

	}

	return mp_decodedDName;

}

// --------------------------------------------------------------------------------
//           Create and Set functions
// --------------------------------------------------------------------------------

DOMElement * DSIGKeyInfoName::createBlankKeyName(const XMLCh * name, bool isDName) {

	// Create the DOM Structure

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

	makeQName(str, prefix, "KeyName");

	DOMElement *ret = doc->createElementNS(DSIGConstants::s_unicodeStrURIDSIG, str.rawXMLChBuffer());
	mp_keyInfoDOMNode = ret;

	// Check whether to encode prior to adding
	if (isDName == true) {

		// Treat as a distinguished name

		mp_decodedDName = XMLString::replicate(name);
		XMLCh * encodedName = encodeDName(name);
		mp_keyNameTextNode = doc->createTextNode(encodedName);
		XSEC_RELEASE_XMLCH(encodedName);
	}

	else
		mp_keyNameTextNode = doc->createTextNode(name);

	ret->appendChild(mp_keyNameTextNode);

	mp_name = mp_keyNameTextNode->getNodeValue();

	return ret;

}

void DSIGKeyInfoName::setKeyName(const XMLCh * name, bool isDName) {

	if (mp_keyNameTextNode == 0) {

		// Attempt to load an empty element
		throw XSECException(XSECException::LoadEmptySignature,
			MAKE_UNICODE_STRING("KeyInfoName::set() called prior to load() or createBlank()"));

	}

	if (mp_decodedDName != NULL) {

		XSEC_RELEASE_XMLCH(mp_decodedDName);
		mp_decodedDName = NULL;

	}

	if (isDName == true) {

		// This name should be treated as a Distinguished Name - so do the
		// required encoding

		mp_decodedDName = XMLString::replicate(name);
		XMLCh * encodedName = encodeDName(name);
		mp_keyNameTextNode->setNodeValue(encodedName);
		XSEC_RELEASE_XMLCH(encodedName);
	}

	else {

		mp_keyNameTextNode->setNodeValue(name);

	}

	mp_name = mp_keyNameTextNode->getNodeValue();

}
