/**************************************************************
 * 
 * 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_embeddedobj.hxx"
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/embed/EntryInitModes.hpp>
#include <com/sun/star/embed/XEmbedObjectFactory.hpp>
#include <com/sun/star/embed/XLinkFactory.hpp>
#include <com/sun/star/document/XTypeDetection.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/lang/XComponent.hpp>

#include <rtl/logfile.hxx>


#include <xcreator.hxx>
#include <dummyobject.hxx>


using namespace ::com::sun::star;


//-------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetSupportedServiceNames()
{
    uno::Sequence< ::rtl::OUString > aRet(2);
    aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.embed.EmbeddedObjectCreator");
    aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.EmbeddedObjectCreator");
    return aRet;
}

//-------------------------------------------------------------------------
::rtl::OUString SAL_CALL UNOEmbeddedObjectCreator::impl_staticGetImplementationName()
{
    return ::rtl::OUString::createFromAscii("com.sun.star.comp.embed.EmbeddedObjectCreator");
}

//-------------------------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::impl_staticCreateSelfInstance(
			const uno::Reference< lang::XMultiServiceFactory >& xServiceManager )
{
	return uno::Reference< uno::XInterface >( *new UNOEmbeddedObjectCreator( xServiceManager ) );
}

//-------------------------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitNew(
											const uno::Sequence< sal_Int8 >& aClassID,
											const ::rtl::OUString& aClassName,
											const uno::Reference< embed::XStorage >& xStorage,
											const ::rtl::OUString& sEntName,
											const uno::Sequence< beans::PropertyValue >& lObjArgs )
	throw ( lang::IllegalArgumentException,
			io::IOException,
			uno::Exception,
			uno::RuntimeException)
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitNew" );

	uno::Reference< uno::XInterface > xResult;

	if ( !xStorage.is() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											3 );

	if ( !sEntName.getLength() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											4 );

	::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
	if ( !aEmbedFactory.getLength() )
	{
		// use system fallback
		// TODO: in future users factories can be tested
		aEmbedFactory = ::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" );
	}

    uno::Reference < uno::XInterface > xFact( m_xFactory->createInstance( aEmbedFactory ) );
    uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY );
    if ( xEmbCreator.is() )
        return xEmbCreator->createInstanceInitNew( aClassID, aClassName, xStorage, sEntName, lObjArgs );

    uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY );
    if ( !xEmbFact.is() )
        throw uno::RuntimeException();
    return xEmbFact->createInstanceUserInit( aClassID, aClassName, xStorage, sEntName, embed::EntryInitModes::TRUNCATE_INIT, uno::Sequence < beans::PropertyValue >(), lObjArgs);
}

//-------------------------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromEntry(
																	const uno::Reference< embed::XStorage >& xStorage,
																	const ::rtl::OUString& sEntName,
																	const uno::Sequence< beans::PropertyValue >& aMedDescr,
																	const uno::Sequence< beans::PropertyValue >& lObjArgs )
	throw ( lang::IllegalArgumentException,
			container::NoSuchElementException,
			io::IOException,
			uno::Exception,
			uno::RuntimeException)
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromEntry" );

	if ( !xStorage.is() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											1 );

	if ( !sEntName.getLength() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											2 );

	uno::Reference< container::XNameAccess > xNameAccess( xStorage, uno::UNO_QUERY );
	if ( !xNameAccess.is() )
		throw uno::RuntimeException(); //TODO

	// detect entry existence
	if ( !xNameAccess->hasByName( sEntName ) )
		throw container::NoSuchElementException();

	::rtl::OUString aMediaType;
	::rtl::OUString aEmbedFactory;
	if ( xStorage->isStorageElement( sEntName ) )
	{
		// the object must be based on storage
		uno::Reference< embed::XStorage > xSubStorage =
				xStorage->openStorageElement( sEntName, embed::ElementModes::READ );

		uno::Reference< beans::XPropertySet > xPropSet( xSubStorage, uno::UNO_QUERY );
		if ( !xPropSet.is() )
			throw uno::RuntimeException();

		try {
			uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
			aAny >>= aMediaType;
		}
		catch ( uno::Exception& )
		{
		}

		try {
			uno::Reference< lang::XComponent > xComp( xSubStorage, uno::UNO_QUERY );
			if ( xComp.is() )
				xComp->dispose();
		}
		catch ( uno::Exception& )
		{
		}
	}
	else
	{
		// the object must be based on stream
		// it means for now that this is an OLE object

		// the object will be created as embedded object
		// after it is loaded it can detect that it is a link

		uno::Reference< io::XStream > xSubStream =
				xStorage->openStreamElement( sEntName, embed::ElementModes::READ );

		uno::Reference< beans::XPropertySet > xPropSet( xSubStream, uno::UNO_QUERY );
		if ( !xPropSet.is() )
			throw uno::RuntimeException();

		try {
			uno::Any aAny = xPropSet->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) );
			aAny >>= aMediaType;
            if ( aMediaType.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.sun.star.oleobject" ) ) ) )
                aEmbedFactory = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) );
		}
		catch ( uno::Exception& )
		{
		}

		try {
			uno::Reference< lang::XComponent > xComp( xSubStream, uno::UNO_QUERY );
			if ( xComp.is() )
				xComp->dispose();
		}
		catch ( uno::Exception& )
		{
		}
	}

	OSL_ENSURE( aMediaType.getLength(), "No media type is specified for the object!" );
	if ( aMediaType.getLength() && !aEmbedFactory.getLength() )
		aEmbedFactory = m_aConfigHelper.GetFactoryNameByMediaType( aMediaType );

	if ( aEmbedFactory.getLength() )
	{
        uno::Reference< uno::XInterface > xFact = m_xFactory->createInstance( aEmbedFactory );

		uno::Reference< embed::XEmbedObjectCreator > xEmbCreator( xFact, uno::UNO_QUERY );
		if ( xEmbCreator.is() )
		    return xEmbCreator->createInstanceInitFromEntry( xStorage, sEntName, aMedDescr, lObjArgs );

        uno::Reference < embed::XEmbedObjectFactory > xEmbFact( xFact, uno::UNO_QUERY );
        if ( xEmbFact.is() )
            return xEmbFact->createInstanceUserInit( uno::Sequence< sal_Int8 >(), ::rtl::OUString(), xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs);
	}

	// the default object should be created, it will allow to store the contents on the next saving
	uno::Reference< uno::XInterface > xResult( static_cast< cppu::OWeakObject* >( new ODummyEmbeddedObject() ) );
	uno::Reference< embed::XEmbedPersist > xPersist( xResult, uno::UNO_QUERY_THROW );
	xPersist->setPersistentEntry( xStorage, sEntName, embed::EntryInitModes::DEFAULT_INIT, aMedDescr, lObjArgs );
	return xResult;
}

//-------------------------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor(
		const uno::Reference< embed::XStorage >& xStorage,
		const ::rtl::OUString& sEntName,
		const uno::Sequence< beans::PropertyValue >& aMediaDescr,
		const uno::Sequence< beans::PropertyValue >& lObjArgs )
	throw ( lang::IllegalArgumentException,
			io::IOException,
			uno::Exception,
			uno::RuntimeException)
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceInitFromMediaDescriptor" );

	// TODO: use lObjArgs

	if ( !xStorage.is() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											1 );

	if ( !sEntName.getLength() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											2 );

	uno::Reference< uno::XInterface > xResult;
	uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );

	// check if there is FilterName
	::rtl::OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, sal_False );

	if ( aFilterName.getLength() )
	{
		// the object can be loaded by one of the office application
		uno::Reference< embed::XEmbedObjectCreator > xOOoEmbCreator(
							m_xFactory->createInstance(
									::rtl::OUString::createFromAscii( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) ),
							uno::UNO_QUERY );
		if ( !xOOoEmbCreator.is() )
			throw uno::RuntimeException(); // TODO:

		xResult = xOOoEmbCreator->createInstanceInitFromMediaDescriptor( xStorage,
														 				sEntName,
														 				aTempMedDescr,
														 				lObjArgs );
	}
	else
	{
		// must be an OLE object

		// TODO: in future, when more object types are possible this place seems
		// to be a weak one, probably configuration must provide a type detection service
		// for every factory, so any file could go through services until it is recognized
		// or there is no more services
		// Or for example the typename can be used to detect object type if typedetection
		// was also extended.

		uno::Reference< embed::XEmbedObjectCreator > xOleEmbCreator(
							m_xFactory->createInstance(
									::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ),
							uno::UNO_QUERY );
		if ( !xOleEmbCreator.is() )
			throw uno::RuntimeException(); // TODO:

		xResult = xOleEmbCreator->createInstanceInitFromMediaDescriptor( xStorage, sEntName, aTempMedDescr, lObjArgs );
	}

	return xResult;
}

//-------------------------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceUserInit(
		const uno::Sequence< sal_Int8 >& aClassID,
		const ::rtl::OUString& sClassName,
		const uno::Reference< embed::XStorage >& xStorage,
		const ::rtl::OUString& sEntName,
		sal_Int32 nEntryConnectionMode,
		const uno::Sequence< beans::PropertyValue >& aArgs,
		const uno::Sequence< beans::PropertyValue >& aObjectArgs )
	throw ( lang::IllegalArgumentException,
			io::IOException,
			uno::Exception,
			uno::RuntimeException)
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceUserInit" );

	uno::Reference< uno::XInterface > xResult;

	if ( !xStorage.is() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											3 );

	if ( !sEntName.getLength() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
											uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
											4 );

	::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
	uno::Reference< embed::XEmbedObjectFactory > xEmbFactory(
						m_xFactory->createInstance( aEmbedFactory ),
						uno::UNO_QUERY );
	if ( !xEmbFactory.is() )
		throw uno::RuntimeException(); // TODO:

	return xEmbFactory->createInstanceUserInit( aClassID,
												sClassName,
												xStorage,
												sEntName,
												nEntryConnectionMode,
												aArgs,
												aObjectArgs );
}

//-------------------------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLink(
											const uno::Reference< embed::XStorage >& xStorage,
											const ::rtl::OUString& sEntName,
											const uno::Sequence< beans::PropertyValue >& aMediaDescr,
											const uno::Sequence< beans::PropertyValue >& lObjArgs )
		throw ( lang::IllegalArgumentException,
				io::IOException,
				uno::Exception,
				uno::RuntimeException )
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLink" );

	uno::Reference< uno::XInterface > xResult;

	uno::Sequence< beans::PropertyValue > aTempMedDescr( aMediaDescr );

	// check if there is URL, URL must exist
	::rtl::OUString aURL;
	for ( sal_Int32 nInd = 0; nInd < aTempMedDescr.getLength(); nInd++ )
		if ( aTempMedDescr[nInd].Name.equalsAscii( "URL" ) )
			aTempMedDescr[nInd].Value >>= aURL;

	if ( !aURL.getLength() )
		throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No URL for the link is provided!\n" ),
										uno::Reference< uno::XInterface >( static_cast< ::cppu::OWeakObject* >(this) ),
										3 );

	::rtl::OUString aFilterName = m_aConfigHelper.UpdateMediaDescriptorWithFilterName( aTempMedDescr, sal_False );

	if ( aFilterName.getLength() )
	{
		// the object can be loaded by one of the office application
		uno::Reference< embed::XLinkCreator > xOOoLinkCreator(
							m_xFactory->createInstance(
									::rtl::OUString::createFromAscii( "com.sun.star.embed.OOoEmbeddedObjectFactory" ) ),
							uno::UNO_QUERY );
		if ( !xOOoLinkCreator.is() )
			throw uno::RuntimeException(); // TODO:

		xResult = xOOoLinkCreator->createInstanceLink( xStorage,
														sEntName,
														aTempMedDescr,
														lObjArgs );
	}
	else
	{
		// must be an OLE link

		// TODO: in future, when more object types are possible this place seems
		// to be a weak one, probably configuration must provide a type detection service
		// for every factory, so any file could go through services until it is recognized
		// or there is no more services
		// Or for example the typename can be used to detect object type if typedetection
		// was also extended.

		if ( !xStorage.is() )
			throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "No parent storage is provided!\n" ),
												uno::Reference< uno::XInterface >(
													static_cast< ::cppu::OWeakObject* >(this) ),
												3 );

		if ( !sEntName.getLength() )
			throw lang::IllegalArgumentException( ::rtl::OUString::createFromAscii( "Empty element name is provided!\n" ),
												uno::Reference< uno::XInterface >(
													static_cast< ::cppu::OWeakObject* >(this) ),
												4 );

		uno::Reference< embed::XLinkCreator > xLinkCreator(
							m_xFactory->createInstance(
								::rtl::OUString::createFromAscii( "com.sun.star.embed.OLEEmbeddedObjectFactory" ) ),
							uno::UNO_QUERY );
		if ( !xLinkCreator.is() )
			throw uno::RuntimeException(); // TODO:

		xResult = xLinkCreator->createInstanceLink( xStorage, sEntName, aTempMedDescr, lObjArgs );
	}

	return xResult;
}

//-------------------------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL UNOEmbeddedObjectCreator::createInstanceLinkUserInit(
												const uno::Sequence< sal_Int8 >& aClassID,
												const ::rtl::OUString& aClassName,
												const uno::Reference< embed::XStorage >& xStorage,
												const ::rtl::OUString& sEntName,
												const uno::Sequence< beans::PropertyValue >& lArguments,
												const uno::Sequence< beans::PropertyValue >& lObjArgs )
		throw ( lang::IllegalArgumentException,
				io::IOException,
				uno::Exception,
				uno::RuntimeException )
{
	RTL_LOGFILE_CONTEXT( aLog, "embeddedobj (mv76033) UNOEmbeddedObjectCreator::createInstanceLinkUserInit" );

	uno::Reference< uno::XInterface > xResult;

	::rtl::OUString aEmbedFactory = m_aConfigHelper.GetFactoryNameByClassID( aClassID );
	uno::Reference< embed::XLinkFactory > xLinkFactory(
						m_xFactory->createInstance( aEmbedFactory ),
						uno::UNO_QUERY );
	if ( !xLinkFactory.is() )
		throw uno::RuntimeException(); // TODO:

	return xLinkFactory->createInstanceLinkUserInit( aClassID,
													aClassName,
													xStorage,
													sEntName,
													lArguments,
													lObjArgs );

}

//-------------------------------------------------------------------------
::rtl::OUString SAL_CALL UNOEmbeddedObjectCreator::getImplementationName()
	throw ( uno::RuntimeException )
{
	return impl_staticGetImplementationName();
}

//-------------------------------------------------------------------------
sal_Bool SAL_CALL UNOEmbeddedObjectCreator::supportsService( const ::rtl::OUString& ServiceName )
	throw ( uno::RuntimeException )
{
	uno::Sequence< ::rtl::OUString > aSeq = impl_staticGetSupportedServiceNames();

	for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
    	if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
        	return sal_True;

	return sal_False;
}

//-------------------------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL UNOEmbeddedObjectCreator::getSupportedServiceNames()
	throw ( uno::RuntimeException )
{
	return impl_staticGetSupportedServiceNames();
}

