/**
 * 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
 *
 * XENCCipherValueImpl := Implementation for CipherValue elements
 *
 * $Id: XENCCipherValueImpl.cpp 1833341 2018-06-11 16:25:41Z scantor $
 *
 */

// XSEC Includes

#include <xsec/framework/XSECDefs.hpp>
#include <xsec/framework/XSECError.hpp>
#include <xsec/framework/XSECEnv.hpp>

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

#include <xercesc/util/XMLUniDefs.hpp>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//			String Constants
// --------------------------------------------------------------------------------

static XMLCh s_CipherValue[] = {

	chLatin_C,
	chLatin_i,
	chLatin_p,
	chLatin_h,
	chLatin_e,
	chLatin_r,
	chLatin_V,
	chLatin_a,
	chLatin_l,
	chLatin_u,
	chLatin_e,
	chNull,
};

XENCCipherValue* XENCCipherValue::create(
	const XSECEnv* env,
	const XMLCh * value)
{

	XENCCipherValueImpl* ret = new XENCCipherValueImpl(env);
	if (!ret)
		throw XSECException(XSECException::MemoryAllocationFail);
	ret->createBlankCipherValue(value);
	return ret;
}

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

XENCCipherValueImpl::XENCCipherValueImpl(const XSECEnv * env) :
mp_env(env),
mp_cipherValueElement(NULL),
mp_cipherString(NULL) {

}

XENCCipherValueImpl::XENCCipherValueImpl(const XSECEnv * env, DOMElement * node) :
mp_env(env),
mp_cipherValueElement(node),
mp_cipherString(NULL) {

}


XENCCipherValueImpl::~XENCCipherValueImpl() {

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

}

// --------------------------------------------------------------------------------
//			Load
// --------------------------------------------------------------------------------

void XENCCipherValueImpl::load(void) {

	if (mp_cipherValueElement == NULL) {

		// Attempt to load an empty encryptedType element
		throw XSECException(XSECException::CipherValueError,
			"XENCCipherData::load - called on empty DOM");

	}

	if (!strEquals(getXENCLocalName(mp_cipherValueElement), s_CipherValue)) {
	
		throw XSECException(XSECException::CipherValueError,
			"XENCCipherData::load - called incorrect node");
	
	}

	// Just gather the text children and continue
	safeBuffer txt;

	gatherChildrenText(mp_cipherValueElement, txt);

	// Get a copy
	mp_cipherString = XMLString::replicate(txt.rawXMLChBuffer());

}

// --------------------------------------------------------------------------------
//			Create a blank structure
// --------------------------------------------------------------------------------

DOMElement * XENCCipherValueImpl::createBlankCipherValue(
						const XMLCh * value) {

	// Rest
	if (mp_cipherString != NULL) {
		XSEC_RELEASE_XMLCH(mp_cipherString);
		mp_cipherString = NULL;
	}

	// Get some setup values
	safeBuffer str;
	DOMDocument *doc = mp_env->getParentDocument();
	const XMLCh * prefix = mp_env->getXENCNSPrefix();

	makeQName(str, prefix, s_CipherValue);

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

	// Append the value
	ret->appendChild(doc->createTextNode(value));
	
	mp_cipherString = XMLString::replicate(value);;

	return ret;

}

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

const XMLCh * XENCCipherValueImpl::getCipherString(void) const {

	return mp_cipherString;

}

void XENCCipherValueImpl::setCipherString(const XMLCh * value) {

	if (mp_cipherValueElement == NULL) {

		throw XSECException(XSECException::CipherValueError,
			"XENCCipherData::setCipherString - called on empty DOM");

	}

	// Find first text child
	DOMNode * txt = findFirstChildOfType(mp_cipherValueElement, DOMNode::TEXT_NODE);
	
	if (txt == NULL) {
		throw XSECException(XSECException::CipherValueError,
			"XENCCipherData::setCipherString - Error finding text node");
	}

	txt->setNodeValue(value);

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

	mp_cipherString = XMLString::replicate(value);

}
