/**************************************************************
 *
 * 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_xmlhelp.hxx"

#define WORKAROUND_98119

#ifdef WORKAROUND_98119
#include "bufferedinputstream.hxx"
#endif

#include <string.h>
#ifndef _VOS_DIAGNOSE_HXX_
#include <vos/diagnose.hxx>
#endif
#include <osl/thread.h>
#include <rtl/memory.h>
#include <osl/file.hxx>
#include <cppuhelper/weak.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <comphelper/processfactory.hxx>
#include <rtl/uri.hxx>
#include <rtl/ustrbuf.hxx>
#include <libxslt/xslt.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
#include <libxslt/security.h>
#include "db.hxx"
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
#include <com/sun/star/ucb/OpenMode.hpp>
#include <com/sun/star/ucb/XCommandProcessor.hpp>
#include <com/sun/star/ucb/XCommandEnvironment.hpp>
#include <com/sun/star/ucb/XContentIdentifier.hpp>
#include <com/sun/star/ucb/XContentProvider.hpp>
#include <com/sun/star/ucb/XContentIdentifierFactory.hpp>
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>

#include "urlparameter.hxx"
#include "databases.hxx"

namespace chelp {

	inline bool ascii_isDigit( sal_Unicode ch )
	{
		return ((ch >= 0x0030) && (ch <= 0x0039));
	}

	inline bool ascii_isLetter( sal_Unicode ch )
	{
		return ( ( (ch >= 0x0041) && (ch <= 0x005A) ) ||
				 ( (ch >= 0x0061) && (ch <= 0x007A) ) );
	}

	inline bool isLetterOrDigit( sal_Unicode ch )
	{
		return ascii_isLetter( ch ) || ascii_isDigit( ch );
	}

}

using namespace cppu;
using namespace com::sun::star::io;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::ucb;
using namespace com::sun::star::beans;
using namespace com::sun::star::container;
using namespace chelp;


URLParameter::URLParameter( const rtl::OUString& aURL,
							Databases* pDatabases )
	throw( com::sun::star::ucb::IllegalIdentifierException )
	: m_pDatabases( pDatabases ),
      m_aURL( aURL )
{
	init( false );
	parse();
}


bool URLParameter::isErrorDocument()
{
	bool bErrorDoc = false;

	if( isFile() )
	{
		Reference< XHierarchicalNameAccess > xNA =
			m_pDatabases->findJarFileForPath( get_jar(), get_language(), get_path() );
		bErrorDoc = !xNA.is();
	}

	return bErrorDoc;
}


rtl::OString URLParameter::getByName( const char* par )
{
	rtl::OUString val;

	if( strcmp( par,"Program" ) == 0 )
		val = get_program();
	else if( strcmp( par,"Database" ) == 0 )
		val = get_module();
	else if( strcmp( par,"DatabasePar" ) == 0 )
		val = get_dbpar();
	else if( strcmp( par,"Id" ) == 0 )
		val = get_id();
	else if( strcmp( par,"Path" ) == 0 )
		val = get_path();
	else if( strcmp( par,"Language" ) == 0 )
		val = get_language();
	else if( strcmp( par,"System" ) == 0 )
		val = get_system();
	else if( strcmp( par,"HelpPrefix" ) == 0 )
		val = get_prefix();

	return rtl::OString( val.getStr(),val.getLength(),RTL_TEXTENCODING_UTF8 );
}


rtl::OUString URLParameter::get_id()
{
	if( m_aId.compareToAscii("start") == 0 )
	{   // module is set
		StaticModuleInformation* inf =
			m_pDatabases->getStaticInformationForModule( get_module(),
														 get_language() );
		if( inf )
			m_aId = inf->get_id();

		m_bStart = true;
	}

	return m_aId;
}

rtl::OUString URLParameter::get_tag()
{
	if( isFile() )
		return get_the_tag();
	else
		return m_aTag;
}


rtl::OUString URLParameter::get_title()
{
	if( isFile() )
		return get_the_title();
	else if( m_aModule.compareToAscii("") != 0 )
	{
		StaticModuleInformation* inf =
			m_pDatabases->getStaticInformationForModule( get_module(),
														 get_language() );
		if( inf )
			m_aTitle = inf->get_title();
	}
	else   // This must be the root
		m_aTitle = rtl::OUString::createFromAscii("root");

	return m_aTitle;
}


rtl::OUString URLParameter::get_language()
{
	if( m_aLanguage.getLength() == 0 )
		return m_aDefaultLanguage;

	return m_aLanguage;
}


rtl::OUString URLParameter::get_program()
{
	if( ! m_aProgram.getLength() )
	{
		StaticModuleInformation* inf =
			m_pDatabases->getStaticInformationForModule( get_module(),
														 get_language() );
		if( inf )
			m_aProgram = inf->get_program();
	}
	return m_aProgram;
}


void URLParameter::init( bool bDefaultLanguageIsInitialized )
{
	(void)bDefaultLanguageIsInitialized;

	m_bHelpDataFileRead = false;
	m_bStart = false;
    m_bUseDB = true;
	m_nHitCount = 100;                // The default maximum hitcount
}


rtl::OUString URLParameter::get_the_tag()
{
    if(m_bUseDB) {
        if( ! m_bHelpDataFileRead )
            readHelpDataFile();

        m_bHelpDataFileRead = true;

        return m_aTag;
    }
    else
        return rtl::OUString();
}



rtl::OUString URLParameter::get_the_path()
{
    if(m_bUseDB) {
        if( ! m_bHelpDataFileRead )
            readHelpDataFile();
        m_bHelpDataFileRead = true;

        return m_aPath;
    }
    else
        return get_id();
}



rtl::OUString URLParameter::get_the_title()
{
    if(m_bUseDB) {
        if( ! m_bHelpDataFileRead )
            readHelpDataFile();
        m_bHelpDataFileRead = true;

        return m_aTitle;
    }
    else
        return rtl::OUString();
}


rtl::OUString URLParameter::get_the_jar()
{
    if(m_bUseDB) {
        if( ! m_bHelpDataFileRead )
            readHelpDataFile();
        m_bHelpDataFileRead = true;

        return m_aJar;
    }
    else
        return get_module() + rtl::OUString::createFromAscii(".jar");
}




void URLParameter::readHelpDataFile()
{
	static rtl::OUString aQuestionMark( rtl::OUString::createFromAscii( "?" ) );

	if( get_id().compareToAscii("") == 0 )
		return;

	rtl::OUString aModule = get_module();
	rtl::OUString aLanguage = get_language();

	DataBaseIterator aDbIt( *m_pDatabases, aModule, aLanguage, false );
	bool bSuccess = false;

	int nSize = 0;
	const sal_Char* pData = NULL;

	helpdatafileproxy::HDFData aHDFData;
	rtl::OUString aExtensionPath;
    rtl::OUString aExtensionRegistryPath;
	while( true )
	{
		helpdatafileproxy::Hdf* pHdf = aDbIt.nextHdf( &aExtensionPath, &aExtensionRegistryPath );
		if( !pHdf )
			break;

		rtl::OString keyStr( m_aId.getStr(),m_aId.getLength(),RTL_TEXTENCODING_UTF8 );

		bSuccess = pHdf->getValueForKey( keyStr, aHDFData );
		if( bSuccess )
		{
			nSize = aHDFData.getSize();
			pData = aHDFData.getData();
			break;
		}
	}

	if( bSuccess )
	{
		DbtToStringConverter converter( pData, nSize );
		m_aTitle = converter.getTitle();
		m_pDatabases->replaceName( m_aTitle );
		m_aPath  = converter.getFile();
		m_aJar   = converter.getDatabase();
		if( aExtensionPath.getLength() > 0 )
		{
			rtl::OUStringBuffer aExtendedJarStrBuf;
			aExtendedJarStrBuf.append( aQuestionMark );
			aExtendedJarStrBuf.append( aExtensionPath );
			aExtendedJarStrBuf.append( aQuestionMark );
			aExtendedJarStrBuf.append( m_aJar );
			m_aJar = aExtendedJarStrBuf.makeStringAndClear();
            m_aExtensionRegistryPath = aExtensionRegistryPath;
		}
		m_aTag   = converter.getHash();
	}
}



// Class encapsulating the transformation of the XInputStream to XHTML


class InputStreamTransformer
	: public OWeakObject,
	  public XInputStream,
	  public XSeekable
{
public:

	InputStreamTransformer( URLParameter* urlParam,
							Databases*    pDatatabases,
							bool isRoot = false );

	~InputStreamTransformer();

	virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
	virtual void SAL_CALL acquire( void ) throw();
	virtual void SAL_CALL release( void ) throw();

	virtual sal_Int32 SAL_CALL readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead )
		throw( NotConnectedException,
			   BufferSizeExceededException,
			   IOException,
			   RuntimeException);

	virtual sal_Int32 SAL_CALL readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
		throw( NotConnectedException,
			   BufferSizeExceededException,
			   IOException,
			   RuntimeException);

	virtual void SAL_CALL skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException,
																	 BufferSizeExceededException,
																	 IOException,
																	 RuntimeException );

	virtual sal_Int32 SAL_CALL available( void ) throw( NotConnectedException,
														IOException,
														RuntimeException );

	virtual void SAL_CALL closeInput( void ) throw( NotConnectedException,
													IOException,
													RuntimeException );

	virtual void SAL_CALL seek( sal_Int64 location ) throw( IllegalArgumentException,
															IOException,
															RuntimeException );

	virtual sal_Int64 SAL_CALL getPosition( void ) throw( IOException,RuntimeException );

	virtual sal_Int64 SAL_CALL getLength( void ) throw( IOException,RuntimeException );

	void addToBuffer( const char* buffer,int len );

	sal_Int8* getData() const { return (sal_Int8*) buffer; }

    sal_Int32 getLen() const { return sal_Int32( len ); }

private:

	osl::Mutex m_aMutex;

	int len,pos;
	char *buffer;
};



void URLParameter::open( const Reference< XMultiServiceFactory >& rxSMgr,
						 const Command& aCommand,
						 sal_Int32 CommandId,
						 const Reference< XCommandEnvironment >& Environment,
						 const Reference< XOutputStream >& xDataSink )
{
	(void)rxSMgr;
	(void)aCommand;
	(void)CommandId;
	(void)Environment;

    if( ! xDataSink.is() )
        return;

	if( isPicture() )
	{
		Reference< XInputStream > xStream;
		Reference< XHierarchicalNameAccess > xNA =
			m_pDatabases->jarFile( rtl::OUString::createFromAscii( "picture.jar" ),
								   get_language() );

		rtl::OUString path = get_path();
		if( xNA.is() )
		{
			try
			{
				Any aEntry = xNA->getByHierarchicalName( path );
				Reference< XActiveDataSink > xSink;
				if( ( aEntry >>= xSink ) && xSink.is() )
					xStream = xSink->getInputStream();
			}
			catch ( NoSuchElementException & )
			{
			}
		}
        if( xStream.is() )
        {
            sal_Int32 ret;
            Sequence< sal_Int8 > aSeq( 4096 );
            while( true )
            {
                try
                {
                    ret = xStream->readBytes( aSeq,4096 );
                    xDataSink->writeBytes( aSeq );
                    if( ret < 4096 )
                        break;
                }
                catch( const Exception& )
                {
                    break;
                }
            }
        }
	}
	else
    {
		// a standard document or else an active help text, plug in the new input stream
		InputStreamTransformer* p = new InputStreamTransformer( this,m_pDatabases,isRoot() );
        try
        {
            xDataSink->writeBytes( Sequence< sal_Int8 >( p->getData(),p->getLen() ) );
        }
        catch( const Exception& )
        {
        }
        delete p;
    }
    xDataSink->closeOutput();
}



void URLParameter::open( const Reference< XMultiServiceFactory >& rxSMgr,
						 const Command& aCommand,
						 sal_Int32 CommandId,
						 const Reference< XCommandEnvironment >& Environment,
						 const Reference< XActiveDataSink >& xDataSink )
{
	(void)rxSMgr;
	(void)aCommand;
	(void)CommandId;
	(void)Environment;

	if( isPicture() )
	{
		Reference< XInputStream > xStream;
		Reference< XHierarchicalNameAccess > xNA =
			m_pDatabases->jarFile( rtl::OUString::createFromAscii( "picture.jar" ),
								   get_language() );

		rtl::OUString path = get_path();
		if( xNA.is() )
		{
			try
			{
				Any aEntry = xNA->getByHierarchicalName( path );
				Reference< XActiveDataSink > xSink;
				if( ( aEntry >>= xSink ) && xSink.is() )
					xStream = xSink->getInputStream();
			}
			catch ( NoSuchElementException & )
			{
			}
		}
#ifdef WORKAROUND_98119
		xDataSink->setInputStream( turnToSeekable(xStream) );
#else
		xDataSink->setInputStream( xStream );
#endif
	}
	else
		// a standard document or else an active help text, plug in the new input stream
		xDataSink->setInputStream( new InputStreamTransformer( this,m_pDatabases,isRoot() ) );
}


// #include <stdio.h>

void URLParameter::parse() throw( com::sun::star::ucb::IllegalIdentifierException )
{
    // fprintf(stdout,"url send to xmlhelp: %s\n",(rtl::OUStringToOString(m_aURL,RTL_TEXTENCODING_UTF8).getStr()));
	m_aExpr = m_aURL;

	sal_Int32 lstIdx = m_aExpr.lastIndexOf( sal_Unicode( '#' ) );
	if( lstIdx != -1 )
		m_aExpr = m_aExpr.copy( 0,lstIdx );

	if( ! scheme() ||
        ! name( module() ) ||
        ! query() ||
        ! m_aLanguage.getLength() ||
        ! m_aSystem.getLength() )
		throw com::sun::star::ucb::IllegalIdentifierException();
}


bool URLParameter::scheme()
{
	// Correct extension help links as sometimes the
	// module is missing resulting in a misformed URL
	if( m_aExpr.compareToAscii( "vnd.sun.star.help:///", 21 ) == 0 )
	{
		sal_Int32 nLen = m_aExpr.getLength();
		rtl::OUString aLastStr = m_aExpr.copy( nLen - 6 );
		if( aLastStr.compareToAscii( "DbPAR=" ) == 0 )
		{
			rtl::OUString aNewExpr = m_aExpr.copy( 0, 20 );
			rtl::OUString aSharedStr = rtl::OUString::createFromAscii( "shared" );
			aNewExpr += aSharedStr;
			aNewExpr += m_aExpr.copy( 20 );
			aNewExpr += aSharedStr;
			m_aExpr = aNewExpr;
		}
	}

	for( sal_Int32 nPrefixLen = 20 ; nPrefixLen >= 18 ; --nPrefixLen )
	{
		if( m_aExpr.compareToAscii( "vnd.sun.star.help://", nPrefixLen ) == 0 )
		{
			m_aExpr = m_aExpr.copy( nPrefixLen );
			return true;
		}
	}
	return false;
}


bool URLParameter::module()
{
	sal_Int32 idx = 0,length = m_aExpr.getLength();

	while( idx < length && isLetterOrDigit( (m_aExpr.getStr())[idx] ) )
		++idx;

	if( idx != 0 )
	{
		m_aModule = m_aExpr.copy( 0,idx );
		m_aExpr = m_aExpr.copy( idx );
		return true;
	}
	else
		return false;
}



bool URLParameter::name( bool modulePresent )
{
	// if modulepresent, a name may be present, but must not

	sal_Int32 length = m_aExpr.getLength();

	if( length != 0 && (m_aExpr.getStr())[0] == sal_Unicode( '/' ) )
	{
		sal_Int32 idx = 1;
		while( idx < length && (m_aExpr.getStr())[idx] != '?' )
//                ( isLetterOrDigit( (m_aExpr.getStr())[idx] )
//                  || (m_aExpr.getStr())[idx] == '/'
//                  || (m_aExpr.getStr())[idx] == '.' ))
			++idx;

		if( idx != 1 && ! modulePresent )
			return false;
		else
		{
			m_aId = m_aExpr.copy( 1,idx-1 );
			m_aExpr = m_aExpr.copy( idx );
		}
	}

//    fprintf(stdout,"id %s\n",(rtl::OUStringToOString(m_aId,RTL_TEXTENCODING_UTF8).getStr()));
	return true;
}


bool URLParameter::query()
{
	rtl::OUString query_;

	if( ! m_aExpr.getLength() )
		return true;
	else if( (m_aExpr.getStr())[0] == sal_Unicode( '?' ) )
		query_ = m_aExpr.copy( 1 ).trim();
	else
		return false;


	bool ret = true;
	sal_Int32 delimIdx,equalIdx;
	rtl::OUString parameter,value;

	while( query_.getLength() != 0 )
	{
		delimIdx = query_.indexOf( sal_Unicode( '&' ) );
		equalIdx = query_.indexOf( sal_Unicode( '=' ) );
		parameter = query_.copy( 0,equalIdx ).trim();
		if( delimIdx == -1 )
		{
			value = query_.copy( equalIdx + 1 ).trim();
			query_ = rtl::OUString();
		}
		else
		{
			value = query_.copy( equalIdx+1,delimIdx - equalIdx - 1 ).trim();
			query_ = query_.copy( delimIdx+1 ).trim();
		}

		if( parameter.compareToAscii( "Language" ) == 0 )
			m_aLanguage = value;
		else if( parameter.compareToAscii( "Device" ) == 0 )
			m_aDevice = value;
		else if( parameter.compareToAscii( "Program" ) == 0 )
			m_aProgram = value;
		else if( parameter.compareToAscii( "Eid" ) == 0 )
			m_aEid = value;
		else if( parameter.compareToAscii( "UseDB" ) == 0 )
            m_bUseDB = ! ( value.compareToAscii("no") == 0 );
        else if( parameter.compareToAscii( "DbPAR" ) == 0 )
            m_aDbPar = value;
		else if( parameter.compareToAscii( "Query" ) == 0 )
		{
			if( ! m_aQuery.getLength() )
				m_aQuery = value;
			else
				m_aQuery += ( rtl::OUString::createFromAscii( " " ) + value );
		}
		else if( parameter.compareToAscii( "Scope" ) == 0 )
			m_aScope = value;
		else if( parameter.compareToAscii( "System" ) == 0 )
			m_aSystem = value;
		else if( parameter.compareToAscii( "HelpPrefix" ) == 0 )
			m_aPrefix = rtl::Uri::decode(
                value,
                rtl_UriDecodeWithCharset,
                RTL_TEXTENCODING_UTF8 );
		else if( parameter.compareToAscii( "HitCount" ) == 0 )
			m_nHitCount = value.toInt32();
		else if( parameter.compareToAscii( "Active" ) == 0 )
			m_aActive = value;
		else
			ret = false;
	}

	return ret;
}

struct UserData {

	UserData( InputStreamTransformer* pTransformer,
			  URLParameter*           pInitial,
			  Databases*              pDatabases )
		: m_pTransformer( pTransformer ),
          m_pDatabases( pDatabases ),
		  m_pInitial( pInitial )
	{
	}

	InputStreamTransformer*             m_pTransformer;
	Databases*                          m_pDatabases;
	URLParameter*                       m_pInitial;
};

UserData *ugblData = 0;

extern "C" {

static int
fileMatch(const char * URI) {
	if ((URI != NULL) && !strncmp(URI, "file:/", 6))
        return 1;
    return 0;
}

static int
zipMatch(const char * URI) {
	if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.zip:/", 18))
        return 1;
    return 0;
}

static int
helpMatch(const char * URI) {
	if ((URI != NULL) && !strncmp(URI, "vnd.sun.star.help:/", 19))
        return 1;
    return 0;
}

static void *
fileOpen(const char *URI) {
	osl::File *pRet = new osl::File(rtl::OUString(URI, strlen(URI), RTL_TEXTENCODING_UTF8));
	pRet->open(OpenFlag_Read);
	return pRet;
}

static void *
zipOpen(const char * /*URI*/) {
	rtl::OUString language,jar,path;

	if( ugblData->m_pInitial->get_eid().getLength() )
		return (void*)(new Reference< XHierarchicalNameAccess >);
	else
	{
		jar = ugblData->m_pInitial->get_jar();
		language = ugblData->m_pInitial->get_language();
		path = ugblData->m_pInitial->get_path();
	}

	Reference< XHierarchicalNameAccess > xNA =
		ugblData->m_pDatabases->findJarFileForPath( jar, language, path );

    Reference< XInputStream > xInputStream;

	if( xNA.is() )
	{
		try
		{
			Any aEntry = xNA->getByHierarchicalName( path );
			Reference< XActiveDataSink > xSink;
			if( ( aEntry >>= xSink ) && xSink.is() )
				xInputStream = xSink->getInputStream();
		}
		catch ( NoSuchElementException & )
		{
		}
	}

	if( xInputStream.is() )
	{
		return new Reference<XInputStream>(xInputStream);
	}
	return 0;
}

static void *
helpOpen(const char * URI) {
	rtl::OUString language,jar,path;

	URLParameter urlpar( rtl::OUString::createFromAscii( URI ),
						 ugblData->m_pDatabases );

	jar = urlpar.get_jar();
	language = urlpar.get_language();
	path = urlpar.get_path();

	Reference< XHierarchicalNameAccess > xNA =
		ugblData->m_pDatabases->findJarFileForPath( jar, language, path );

    Reference< XInputStream > xInputStream;

	if( xNA.is() )
	{
		try
		{
			Any aEntry = xNA->getByHierarchicalName( path );
			Reference< XActiveDataSink > xSink;
			if( ( aEntry >>= xSink ) && xSink.is() )
				xInputStream = xSink->getInputStream();
		}
		catch ( NoSuchElementException & )
		{
		}
	}

	if( xInputStream.is() )
		return new Reference<XInputStream>(xInputStream);
	return 0;
}

static int
helpRead(void * context, char * buffer, int len) {
	Reference< XInputStream > *pRef = (Reference< XInputStream >*)context;

	Sequence< sal_Int8 > aSeq;
	len = (*pRef)->readBytes( aSeq,len);
	memcpy(buffer, aSeq.getConstArray(), len);

	return len;
}

static int
zipRead(void * context, char * buffer, int len) {
	if( ugblData->m_pInitial->get_eid().getLength() )
	{
		ugblData->m_pDatabases->popupDocument( ugblData->m_pInitial,&buffer,&len);
		return len;
	}
	else
		return helpRead(context, buffer, len);
}

static int
fileRead(void * context, char * buffer, int len) {
	int nRead = 0;
	osl::File *pFile = (osl::File*)context;
	if (pFile)
	{
		sal_uInt64 uRead = 0;
		if (osl::FileBase::E_None == pFile->read(buffer, len, uRead))
			nRead = static_cast<int>(uRead);
	}
	return nRead;
}

static int
uriClose(void * context) {
	Reference< XInputStream > *pRef = (Reference< XInputStream >*)context;
	delete pRef;
    return 0;
}

static int
fileClose(void * context) {
	osl::File *pFile = (osl::File*)context;
	if (pFile)
	{
		pFile->close();
		delete pFile;
	}
	return 0;
}

} // extern "C"

/*
// For debugging only
extern "C" void StructuredXMLErrorFunction(void *userData, xmlErrorPtr error)
{
	(void)userData;
	(void)error;

	// Reset error handler
	xmlSetStructuredErrorFunc( NULL, NULL );
}
*/

InputStreamTransformer::InputStreamTransformer( URLParameter* urlParam,
												Databases*    pDatabases,
												bool isRoot )
	: len( 0 ),
	  pos( 0 ),
	  buffer( new char[1] ) // Initializing with one element to avoid gcc compiler warning
{
	if( isRoot )
	{
		delete[] buffer;
		pDatabases->cascadingStylesheet( urlParam->get_language(),
										 &buffer,
										 &len );
	}
	else if( urlParam->isActive() )
	{
		delete[] buffer;
		pDatabases->setActiveText( urlParam->get_module(),
								   urlParam->get_language(),
								   urlParam->get_id(),
								   &buffer,
								   &len );
	}
	else
	{
		UserData userData( this,urlParam,pDatabases );

		// Uses the implementation detail, that rtl::OString::getStr returns a zero terminated character-array

		const char* parameter[47];
		rtl::OString parString[46];
		int last = 0;

		parString[last++] = "Program";
		rtl::OString aPureProgramm( urlParam->getByName( "Program" ) );
		parString[last++] = rtl::OString('\'') + aPureProgramm + rtl::OString('\'');
		parString[last++] = "Database";
		parString[last++] = rtl::OString('\'') + urlParam->getByName( "DatabasePar" ) + rtl::OString('\'');
		parString[last++] = "Id";
		parString[last++] = rtl::OString('\'') + urlParam->getByName( "Id" ) + rtl::OString('\'');
		parString[last++] = "Path";
		rtl::OString aPath( urlParam->getByName( "Path" ) );
		parString[last++] = rtl::OString('\'') + aPath + rtl::OString('\'');

		rtl::OString aPureLanguage = urlParam->getByName( "Language" );
		parString[last++] = "Language";
		parString[last++] = rtl::OString('\'') + aPureLanguage + rtl::OString('\'');
		parString[last++] = "System";
		parString[last++] = rtl::OString('\'') + urlParam->getByName( "System" ) + rtl::OString('\'');
		parString[last++] = "productname";
		parString[last++] = rtl::OString('\'') + rtl::OString(
            pDatabases->getProductName().getStr(),
            pDatabases->getProductName().getLength(),
            RTL_TEXTENCODING_UTF8 ) + rtl::OString('\'');
		parString[last++] = "productversion";
		parString[last++] = rtl::OString('\'') +
            rtl::OString(  pDatabases->getProductVersion().getStr(),
                          pDatabases->getProductVersion().getLength(),
                          RTL_TEXTENCODING_UTF8 ) + rtl::OString('\'');

        parString[last++] = "imgrepos";
        parString[last++] = rtl::OString('\'') + pDatabases->getImagesZipFileURL() + rtl::OString('\'');
        parString[last++] = "hp";
        parString[last++] = rtl::OString('\'') + urlParam->getByName( "HelpPrefix" ) + rtl::OString('\'');

        if( parString[last-1].getLength() )
        {
            parString[last++] = "sm";
            parString[last++] = "'vnd.sun.star.help%3A%2F%2F'";
            parString[last++] = "qm";
            parString[last++] = "'%3F'";
            parString[last++] = "es";
            parString[last++] = "'%3D'";
            parString[last++] = "am";
            parString[last++] = "'%26'";
            parString[last++] = "cl";
            parString[last++] = "'%3A'";
            parString[last++] = "sl";
            parString[last++] = "'%2F'";
            parString[last++] = "hm";
            parString[last++] = "'%23'";
            parString[last++] = "cs";
            parString[last++] = "'css'";

            parString[last++] = "vendorname";
            parString[last++] = rtl::OString("''");
            parString[last++] = "vendorversion";
            parString[last++] = rtl::OString("''");
            parString[last++] = "vendorshort";
            parString[last++] = rtl::OString("''");
        }

		// Do we need to add extension path?
		::rtl::OUString aExtensionPath;
		rtl::OUString aJar = urlParam->get_jar();

		bool bAddExtensionPath = false;
        rtl::OUString aExtensionRegistryPath;
        sal_Int32 nQuestionMark1 = aJar.indexOf( sal_Unicode('?') );
        sal_Int32 nQuestionMark2 = aJar.lastIndexOf( sal_Unicode('?') );
		if( nQuestionMark1 != -1 && nQuestionMark2 != -1 && nQuestionMark1 != nQuestionMark2 )
		{
			aExtensionPath = aJar.copy( nQuestionMark1 + 1, nQuestionMark2 - nQuestionMark1 - 1 );
            aExtensionRegistryPath = urlParam->get_ExtensionRegistryPath();
			bAddExtensionPath = true;
		}
		else
		{
			// Path not yet specified, search directly
			Reference< XHierarchicalNameAccess > xNA = pDatabases->findJarFileForPath
				( aJar, urlParam->get_language(), urlParam->get_path(), &aExtensionPath, &aExtensionRegistryPath );
			if( xNA.is() && aExtensionPath.getLength() )
				bAddExtensionPath = true;
		}

		if( bAddExtensionPath )
		{
			Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
			Reference< XPropertySet > xProps( xFactory, UNO_QUERY );
			OSL_ASSERT( xProps.is() );
			Reference< XComponentContext > xContext;
			if (xProps.is())
			{
				xProps->getPropertyValue(
					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
			}
			if( !xContext.is() )
			{
				throw RuntimeException(
					::rtl::OUString::createFromAscii( "InputStreamTransformer::InputStreamTransformer(), no XComponentContext" ),
					Reference< XInterface >() );
			}

			rtl::OUString aOUExpandedExtensionPath = Databases::expandURL( aExtensionRegistryPath, xContext );
			rtl::OString aExpandedExtensionPath = rtl::OUStringToOString( aOUExpandedExtensionPath, osl_getThreadTextEncoding() );

			parString[last++] = "ExtensionPath";
			parString[last++] = rtl::OString('\'') + aExpandedExtensionPath + rtl::OString('\'');

			// ExtensionId
			rtl::OString aPureExtensionId;
			sal_Int32 iSlash = aPath.indexOf( '/' );
			if( iSlash != -1 )
				aPureExtensionId = aPath.copy( 0, iSlash );

			parString[last++] = "ExtensionId";
			parString[last++] = rtl::OString('\'') + aPureExtensionId + rtl::OString('\'');
		}

		for( int i = 0; i < last; ++i )
			parameter[i] = parString[i].getStr();
		parameter[last] = 0;

		rtl::OUString xslURL = pDatabases->getInstallPathAsURL();

		rtl::OString xslURLascii(
			xslURL.getStr(),
			xslURL.getLength(),
			RTL_TEXTENCODING_UTF8);
		xslURLascii += "main_transform.xsl";

        ugblData = &userData;

        xmlInitParser();
        xmlRegisterInputCallbacks(zipMatch, zipOpen, zipRead, uriClose);
        xmlRegisterInputCallbacks(helpMatch, helpOpen, helpRead, uriClose);
		xmlRegisterInputCallbacks(fileMatch, fileOpen, fileRead, fileClose);
		//xmlSetStructuredErrorFunc( NULL, (xmlStructuredErrorFunc)StructuredXMLErrorFunction );

        xsltStylesheetPtr cur =
            xsltParseStylesheetFile((const xmlChar *)xslURLascii.getStr());

        xmlDocPtr doc = xmlParseFile("vnd.sun.star.zip:/");

        xmlDocPtr res = NULL;
        xsltTransformContextPtr transformContext = xsltNewTransformContext(cur, doc);
        if (transformContext)
        {
            xsltSecurityPrefsPtr securityPrefs = xsltNewSecurityPrefs();
            if (securityPrefs)
            {
                xsltSetSecurityPrefs(securityPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityAllow);
                if (xsltSetCtxtSecurityPrefs(securityPrefs, transformContext) == 0)
                {
                    res = xsltApplyStylesheetUser(cur, doc, parameter, NULL, NULL, transformContext);
                    if (res)
                    {
                        xmlChar *doc_txt_ptr=0;
                        int doc_txt_len;
                        xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, res, cur);
                        addToBuffer((const char*)doc_txt_ptr, doc_txt_len);
                        xmlFree(doc_txt_ptr);
                    }
                }
                xsltFreeSecurityPrefs(securityPrefs);
            }
            xsltFreeTransformContext(transformContext);
        }
        xmlPopInputCallbacks();	//filePatch
        xmlPopInputCallbacks();	//helpPatch
        xmlPopInputCallbacks();	//zipMatch
        xmlFreeDoc(res);
        xmlFreeDoc(doc);
        xsltFreeStylesheet(cur);
	}
}


InputStreamTransformer::~InputStreamTransformer()
{
	delete[] buffer;
}


Any SAL_CALL InputStreamTransformer::queryInterface( const Type& rType ) throw( RuntimeException )
{
	Any aRet = ::cppu::queryInterface( rType,
									   SAL_STATIC_CAST( XInputStream*,this ),
									   SAL_STATIC_CAST( XSeekable*,this ) );

	return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
}



void SAL_CALL InputStreamTransformer::acquire( void ) throw()
{
	OWeakObject::acquire();
}



void SAL_CALL InputStreamTransformer::release( void ) throw()
{
	OWeakObject::release();
}



sal_Int32 SAL_CALL InputStreamTransformer::readBytes( Sequence< sal_Int8 >& aData,sal_Int32 nBytesToRead )
	throw( NotConnectedException,
		   BufferSizeExceededException,
		   IOException,
		   RuntimeException)
{
	osl::MutexGuard aGuard( m_aMutex );

	int curr,available_ = len-pos;
	if( nBytesToRead <= available_ )
		curr = nBytesToRead;
	else
		curr = available_;

	if( 0 <= curr && aData.getLength() < curr )
		aData.realloc( curr );

	for( int k = 0; k < curr; ++k )
		aData[k] = buffer[pos++];

	return curr > 0 ? curr : 0;
}


sal_Int32 SAL_CALL InputStreamTransformer::readSomeBytes( Sequence< sal_Int8 >& aData,sal_Int32 nMaxBytesToRead )
	throw( NotConnectedException,
		   BufferSizeExceededException,
		   IOException,
		   RuntimeException)
{
	return readBytes( aData,nMaxBytesToRead );
}



void SAL_CALL InputStreamTransformer::skipBytes( sal_Int32 nBytesToSkip ) throw( NotConnectedException,
																				 BufferSizeExceededException,
																				 IOException,
																				 RuntimeException )
{
	osl::MutexGuard aGuard( m_aMutex );
	while( nBytesToSkip-- ) ++pos;
}



sal_Int32 SAL_CALL InputStreamTransformer::available( void ) throw( NotConnectedException,
																	IOException,
																	RuntimeException )
{
	osl::MutexGuard aGuard( m_aMutex );
	return len-pos > 0 ? len - pos : 0 ;
}



void SAL_CALL InputStreamTransformer::closeInput( void ) throw( NotConnectedException,
																IOException,
																RuntimeException )
{
}



void SAL_CALL InputStreamTransformer::seek( sal_Int64 location ) throw( IllegalArgumentException,
																		IOException,
																		RuntimeException )
{
	osl::MutexGuard aGuard( m_aMutex );
	if( location < 0 )
		throw IllegalArgumentException();
	else
		pos = sal::static_int_cast<sal_Int32>( location );

	if( pos > len )
		pos = len;
}



sal_Int64 SAL_CALL InputStreamTransformer::getPosition( void ) throw( IOException,
																	  RuntimeException )
{
	osl::MutexGuard aGuard( m_aMutex );
	return sal_Int64( pos );
}



sal_Int64 SAL_CALL InputStreamTransformer::getLength( void ) throw( IOException,RuntimeException )
{
	osl::MutexGuard aGuard( m_aMutex );

	return len;
}


void InputStreamTransformer::addToBuffer( const char* buffer_,int len_ )
{
	osl::MutexGuard aGuard( m_aMutex );

	char* tmp = buffer;
	buffer = new char[ len+len_ ];
	rtl_copyMemory( (void*)(buffer),(void*)(tmp),sal_uInt32( len ) );
	rtl_copyMemory( (void*)(buffer+len),(void*)(buffer_),sal_uInt32( len_ ) );
	delete[] tmp;
	len += len_;
}
