/**************************************************************
 *
 * 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.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmlsecurity.hxx"

#include "signatureengine.hxx"
#include <com/sun/star/xml/crypto/XXMLSignatureTemplate.hpp>
#include <com/sun/star/xml/wrapper/XXMLElementWrapper.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>

namespace cssu = com::sun::star::uno;
namespace cssl = com::sun::star::lang;
namespace cssxc = com::sun::star::xml::crypto;
namespace cssxw = com::sun::star::xml::wrapper;

#define SIGNATURE_TEMPLATE "com.sun.star.xml.crypto.XMLSignatureTemplate"

#define	DECLARE_ASCII( SASCIIVALUE )																			\
	rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SASCIIVALUE ) )

SignatureEngine::SignatureEngine( )
	:m_nTotalReferenceNumber(-1)
{
}

bool SignatureEngine::checkReady() const
/****** SignatureEngine/checkReady *******************************************
 *
 *   NAME
 *	checkReady -- checks the conditions for the main operation.
 *
 *   SYNOPSIS
 *	bReady = checkReady( );
 *
 *   FUNCTION
 *	checks whether all following conditions are satisfied:
 *	1. the main operation has't begun yet;
 *	2. the key material is known;
 *	3. the amount of reference is known;
 *	4. all of referenced elements, the key element and the signature
 *	   template are bufferred.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	bReady - true if all conditions are satisfied, false otherwise
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	bool rc = true;

	sal_Int32 nKeyInc = 0;
	if (m_nIdOfKeyEC != 0)
	{
		nKeyInc = 1;
	}

	if (m_bMissionDone ||
	    m_nIdOfKeyEC == -1 ||
	    m_nTotalReferenceNumber == -1 ||
	    m_nTotalReferenceNumber+1+nKeyInc > m_nNumOfResolvedReferences)
	{
		rc = false;
	}

	return rc;
}

void SignatureEngine::tryToPerform( )
    	throw (cssu::Exception, cssu::RuntimeException)
/****** SignatureEngine/tryToPerform *****************************************
 *
 *   NAME
 *	tryToPerform -- tries to perform the signature operation.
 *
 *   SYNOPSIS
 *	tryToPerform( );
 *
 *   FUNCTION
 *	if the situation is ready, perform following operations.
 *	1. prepares a signature template;
 *	2. calls the signature bridge component;
 *	3. clears up all used resources;
 *	4. notifies the result listener;
 *	5. sets the "accomplishment" flag.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	if (checkReady())
	{
		const rtl::OUString ouSignatureTemplate (
			RTL_CONSTASCII_USTRINGPARAM( SIGNATURE_TEMPLATE ) );
		cssu::Reference < cssxc::XXMLSignatureTemplate >
			xSignatureTemplate( mxMSF->createInstance( ouSignatureTemplate ), cssu::UNO_QUERY );

		OSL_ASSERT( xSignatureTemplate.is() );

		cssu::Reference< cssxw::XXMLElementWrapper >
			xXMLElement = m_xSAXEventKeeper->getElement( m_nIdOfTemplateEC );

		xSignatureTemplate->setTemplate(xXMLElement);

		std::vector< sal_Int32 >::const_iterator ii = m_vReferenceIds.begin();

		for( ; ii != m_vReferenceIds.end() ; ++ii )
		{
			xXMLElement = m_xSAXEventKeeper->getElement( *ii );
			xSignatureTemplate->setTarget(xXMLElement);
		}

		/*
		 * set the Uri binding
		 */
		xSignatureTemplate->setBinding( this );

		startEngine( xSignatureTemplate );

		/*
		 * done
		 */
		clearUp( );

		notifyResultListener();

		m_bMissionDone = true;
	}
}

void SignatureEngine::clearUp( ) const
/****** SignatureEngine/clearUp **********************************************
 *
 *   NAME
 *	clearUp -- clear up all resources used by this operation.
 *
 *   SYNOPSIS
 *	clearUp( );
 *
 *   FUNCTION
 *	cleaning resources up includes:
 *	1. releases the ElementCollector for the signature template element;
 *	2. releases ElementCollectors for referenced elements;
 *	3. releases the ElementCollector for the key element, if there is one.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	cssu::Reference < cssxc::sax::XReferenceResolvedBroadcaster >
		xReferenceResolvedBroadcaster( m_xSAXEventKeeper, cssu::UNO_QUERY );
	xReferenceResolvedBroadcaster->removeReferenceResolvedListener(
		m_nIdOfTemplateEC,
		(const cssu::Reference < cssxc::sax::XReferenceResolvedListener >)((SecurityEngine *)this));

	m_xSAXEventKeeper->removeElementCollector(m_nIdOfTemplateEC);

	std::vector< sal_Int32 >::const_iterator ii = m_vReferenceIds.begin();

	for( ; ii != m_vReferenceIds.end() ; ++ii )
	{
		xReferenceResolvedBroadcaster->removeReferenceResolvedListener(
			*ii,
			(const cssu::Reference < cssxc::sax::XReferenceResolvedListener >)((SecurityEngine *)this));
		m_xSAXEventKeeper->removeElementCollector(*ii);
	}

	if (m_nIdOfKeyEC != 0 && m_nIdOfKeyEC != -1)
	{
		m_xSAXEventKeeper->removeElementCollector(m_nIdOfKeyEC);
	}
}

/* XReferenceCollector */
void SAL_CALL SignatureEngine::setReferenceCount( sal_Int32 count )
	throw (cssu::Exception, cssu::RuntimeException)
{
	m_nTotalReferenceNumber = count;
	tryToPerform();
}

void SAL_CALL SignatureEngine::setReferenceId( sal_Int32 id )
	throw (cssu::Exception, cssu::RuntimeException)
{
	m_vReferenceIds.push_back( id );
}

/* XUriBinding */
void SAL_CALL SignatureEngine::setUriBinding(
	const rtl::OUString& uri,
	const cssu::Reference< com::sun::star::io::XInputStream >& aInputStream )
	throw (cssu::Exception, cssu::RuntimeException)
{
	m_vUris.push_back(uri);
	m_vXInputStreams.push_back(aInputStream);
}

cssu::Reference< com::sun::star::io::XInputStream > SAL_CALL SignatureEngine::getUriBinding( const rtl::OUString& uri )
	throw (cssu::Exception, cssu::RuntimeException)
{
	cssu::Reference< com::sun::star::io::XInputStream > xInputStream;

	int size = m_vUris.size();

	for( int i=0; i<size; ++i)
	{
		if (m_vUris[i] == uri)
		{
			xInputStream = m_vXInputStreams[i];
			break;
		}
	}

	return xInputStream;
}
