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

/*
 * Implementation of the I/O interfaces based on stream and URI binding
 */
#include "xmlstreamio.hxx"
#include <rtl/ustring.hxx>
#include "rtl/uri.hxx"

#include <libxml/uri.h>
#include <sal/types.h>
//For reasons that escape me, this is what xmlsec does when size_t is not 4
#if SAL_TYPES_SIZEOFPOINTER != 4
#    define XMLSEC_NO_SIZE_T
#endif
#include <xmlsec/io.h>

#define XMLSTREAMIO_INITIALIZED 0x01
#define XMLSTREAMIO_REGISTERED  0x02

/* Global variables */
/*-
 * Enable stream I/O or not.
 */
static char enableXmlStreamIO = 0x00 ;

::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XUriBinding > m_xUriBinding ;

extern "C"
int xmlStreamMatch( const char* uri )
{
	::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream ;

	if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) &&
		( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) {
		if( uri == NULL || !m_xUriBinding.is() )
			return 0 ;
        //XMLSec first unescapes the uri and  calls this function. For example, we pass the Uri 
        //ObjectReplacements/Object%201 then XMLSec passes ObjectReplacements/Object 1  
        //first. If this failed it would try this 
        //again with the original escaped string. However, it does not get this far, because there
        //is another callback registered by libxml which claims to be able to handle this uri.
        ::rtl::OUString sUri =
            ::rtl::Uri::encode( ::rtl::OUString::createFromAscii( uri ), 
            rtl_UriCharClassUric, rtl_UriEncodeKeepEscapes, RTL_TEXTENCODING_UTF8); 
		xInputStream = m_xUriBinding->getUriBinding( sUri ) ;
        if (!xInputStream.is())
        {
            //Try the the passed in uri directly.
            //For old documents prior OOo 3.0. We did not use URIs then.   
            xInputStream = m_xUriBinding->getUriBinding( 
                ::rtl::OUString::createFromAscii(uri));
        }
	}
    if (xInputStream.is())
        return 1;
    else
	    return 0 ;
}

extern "C"
void* xmlStreamOpen( const char* uri )
{
	::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream ;
	::com::sun::star::io::XInputStream* pInputStream ;

	if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) &&
		( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) {
		if( uri == NULL || !m_xUriBinding.is() )
			return NULL ;

        //see xmlStreamMatch
        ::rtl::OUString sUri =
            ::rtl::Uri::encode( ::rtl::OUString::createFromAscii( uri ), 
            rtl_UriCharClassUric, rtl_UriEncodeKeepEscapes, RTL_TEXTENCODING_UTF8); 
        xInputStream = m_xUriBinding->getUriBinding( sUri ) ;
        if (!xInputStream.is())
        {
            //For old documents.
            //try the the passed in uri directly.
            xInputStream = m_xUriBinding->getUriBinding( 
                ::rtl::OUString::createFromAscii(uri));
        }
	
		if( xInputStream.is() ) {
			pInputStream = xInputStream.get() ;
			pInputStream->acquire() ;
			return ( void* )pInputStream ;
		}
	}

	return NULL ;
}

extern "C"
int xmlStreamRead( void* context, char* buffer, int len )
{
	int numbers ;
	::com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream ;
	::com::sun::star::uno::Sequence< sal_Int8 > outSeqs( len ) ;

	numbers = 0 ;
	if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) &&
		( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) {
		if( context != NULL ) {
			xInputStream = ( com::sun::star::io::XInputStream* )context ;
			if( !xInputStream.is() )
				return 0 ;

			numbers = xInputStream->readBytes( outSeqs, len ) ;
			const sal_Int8* readBytes = ( const sal_Int8* )outSeqs.getArray() ;
			for( int i = 0 ; i < numbers ; i ++ )
				*( buffer + i ) = *( readBytes + i ) ;
		}
	}

	return numbers ;
}

extern "C"
int xmlStreamClose( void * context )
{
	::com::sun::star::io::XInputStream* pInputStream ;

	if( ( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) &&
		( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) {
		if( context != NULL ) {
			pInputStream = ( ::com::sun::star::io::XInputStream* )context ;
			pInputStream->release() ;
		}
	}

	return 0 ;
}

int xmlEnableStreamInputCallbacks()
{
	int cbs = 0 ;

	if( !( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) ) {
		//Register the callbacks into libxml2
		//cbs = xmlRegisterInputCallbacks(
		//			xmlStreamMatch,
		//			xmlStreamOpen,
		//			xmlStreamRead,
		//			xmlStreamClose ) ;
		//if( cbs < 0 ) {
		//	return -1 ;
		//}

		//Register the callbacks into xmlSec
		//In order to make the xmlsec io finding the callbacks firstly,
		//I put the callbacks at the very begining.

		//Cleanup the older callbacks.
		//Notes: all none default callbacks will lose.
		xmlSecIOCleanupCallbacks() ;

		//Register my classbacks.
		cbs = xmlSecIORegisterCallbacks(
					xmlStreamMatch,
					xmlStreamOpen,
					xmlStreamRead,
					xmlStreamClose ) ;
		if( cbs < 0 ) {
			return -1 ;
		}

		//Register the default callbacks.
		//Notes: the error will cause xmlsec working problems.
		cbs = xmlSecIORegisterDefaultCallbacks() ;
		if( cbs < 0 ) {
			return -1 ;
		}

		enableXmlStreamIO |= XMLSTREAMIO_INITIALIZED ;
	}

	return 0 ;
}

int xmlRegisterStreamInputCallbacks(
	::com::sun::star::uno::Reference< ::com::sun::star::xml::crypto::XUriBinding >& aUriBinding
) {
	if( !( enableXmlStreamIO & XMLSTREAMIO_INITIALIZED ) ) {
		if( xmlEnableStreamInputCallbacks() < 0 )
			return -1 ;
	}

	if( !( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) {
		enableXmlStreamIO |= XMLSTREAMIO_REGISTERED ;
	}

	m_xUriBinding = aUriBinding ;

	return 0 ;
}

int xmlUnregisterStreamInputCallbacks( void )
{
	if( ( enableXmlStreamIO & XMLSTREAMIO_REGISTERED ) ) {
		//Clear the uir-stream binding
		m_xUriBinding.clear() ;

		//disable the registered flag
		enableXmlStreamIO &= ~XMLSTREAMIO_REGISTERED ;
	}

	return 0 ;
}

void xmlDisableStreamInputCallbacks() {
	xmlUnregisterStreamInputCallbacks() ;
	enableXmlStreamIO &= ~XMLSTREAMIO_INITIALIZED ;
}

