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

#include <dynamicresultsetwrapper.hxx>
#include <ucbhelper/macros.hxx>
#include <osl/diagnose.h>
#include <rtl/ustring.hxx>
#include <com/sun/star/ucb/ListActionType.hpp>
#include <com/sun/star/ucb/WelcomeDynamicResultSetStruct.hpp>
#include <com/sun/star/ucb/XCachedDynamicResultSetStubFactory.hpp>

using namespace com::sun::star::lang;
using namespace com::sun::star::sdbc;
using namespace com::sun::star::ucb;
using namespace com::sun::star::uno;
using namespace cppu;
using namespace rtl;

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// class DynamicResultSetWrapper
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

DynamicResultSetWrapper::DynamicResultSetWrapper(
					Reference< XDynamicResultSet > xOrigin
					, const Reference< XMultiServiceFactory > & xSMgr )

				: m_bDisposed( sal_False )
				, m_bInDispose( sal_False )
				, m_pDisposeEventListeners( NULL )
                , m_xSMgr( xSMgr )
				, m_bStatic( sal_False )
				, m_bGotWelcome( sal_False )
				, m_xSource( xOrigin )
				, m_xSourceResultOne( NULL )
				, m_xSourceResultTwo( NULL )
			//	, m_xSourceResultCurrent( NULL )
			//	, m_bUseOne( NULL )
				, m_xMyResultOne( NULL )
				, m_xMyResultTwo( NULL )
				, m_xListener( NULL )
{
	m_pMyListenerImpl = new DynamicResultSetWrapperListener( this );
	m_xMyListenerImpl = Reference< XDynamicResultSetListener >( m_pMyListenerImpl );
	//call impl_init() at the end of constructor of derived class
};

void SAL_CALL DynamicResultSetWrapper::impl_init()
{
	//call this at the end of constructor of derived class
	//

	Reference< XDynamicResultSet > xSource = NULL;
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		xSource = m_xSource;
		m_xSource = NULL;
	}
	if( xSource.is() )
		setSource( xSource );
}

DynamicResultSetWrapper::~DynamicResultSetWrapper()
{
	//call impl_deinit() at start of destructor of derived class

	delete m_pDisposeEventListeners;
};

void SAL_CALL DynamicResultSetWrapper::impl_deinit()
{
	//call this at start of destructor of derived class
	//
	m_pMyListenerImpl->impl_OwnerDies();
}

void SAL_CALL DynamicResultSetWrapper
::impl_EnsureNotDisposed()
	throw( DisposedException, RuntimeException )
{
	osl::Guard< osl::Mutex > aGuard( m_aMutex );
	if( m_bDisposed )
		throw DisposedException();
}

//virtual
void SAL_CALL DynamicResultSetWrapper
::impl_InitResultSetOne( const Reference< XResultSet >& xResultSet )
{
	osl::Guard< osl::Mutex > aGuard( m_aMutex );
	OSL_ENSURE( !m_xSourceResultOne.is(), "Source ResultSet One is set already" );
	m_xSourceResultOne = xResultSet;
	m_xMyResultOne = xResultSet;
}

//virtual
void SAL_CALL DynamicResultSetWrapper
::impl_InitResultSetTwo( const Reference< XResultSet >& xResultSet )
{
	osl::Guard< osl::Mutex > aGuard( m_aMutex );
	OSL_ENSURE( !m_xSourceResultTwo.is(), "Source ResultSet Two is set already" );
	m_xSourceResultTwo = xResultSet;
	m_xMyResultTwo = xResultSet;
}

//--------------------------------------------------------------------------
// XInterface methods.
//--------------------------------------------------------------------------
//list all interfaces inclusive baseclasses of interfaces
QUERYINTERFACE_IMPL_START( DynamicResultSetWrapper )
	SAL_STATIC_CAST( XComponent*, this ) //base of XDynamicResultSet
	, SAL_STATIC_CAST( XDynamicResultSet*, this )
	, SAL_STATIC_CAST( XSourceInitialization*, this )
QUERYINTERFACE_IMPL_END

//--------------------------------------------------------------------------
// XComponent methods.
//--------------------------------------------------------------------------
// virtual
void SAL_CALL DynamicResultSetWrapper
	::dispose() throw( RuntimeException )
{
	impl_EnsureNotDisposed();

	Reference< XComponent > xSourceComponent;
	{
		osl::ClearableGuard< osl::Mutex > aGuard( m_aMutex );
		if( m_bInDispose || m_bDisposed )
			return;
		m_bInDispose = sal_True;

		xSourceComponent = Reference< XComponent >(m_xSource, UNO_QUERY);

		if( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
		{
			EventObject aEvt;
			aEvt.Source = static_cast< XComponent * >( this );

			aGuard.clear();
			m_pDisposeEventListeners->disposeAndClear( aEvt );
		}
	}

	/* //@todo ?? ( only if java collection needs to long )
	if( xSourceComponent.is() )
		xSourceComponent->dispose();
	*/

	osl::Guard< osl::Mutex > aGuard( m_aMutex );
	m_bDisposed = sal_True;
	m_bInDispose = sal_False;
}

//--------------------------------------------------------------------------
// virtual
void SAL_CALL DynamicResultSetWrapper
	::addEventListener(	const Reference< XEventListener >& Listener )
	throw( RuntimeException )
{
	impl_EnsureNotDisposed();
	osl::Guard< osl::Mutex > aGuard( m_aMutex );

	if ( !m_pDisposeEventListeners )
		m_pDisposeEventListeners =
					new OInterfaceContainerHelper( m_aContainerMutex );

	m_pDisposeEventListeners->addInterface( Listener );
}

//--------------------------------------------------------------------------
// virtual
void SAL_CALL DynamicResultSetWrapper
	::removeEventListener( const Reference< XEventListener >& Listener )
	throw( RuntimeException )
{
	impl_EnsureNotDisposed();
	osl::Guard< osl::Mutex > aGuard( m_aMutex );

	if ( m_pDisposeEventListeners )
		m_pDisposeEventListeners->removeInterface( Listener );
}

//--------------------------------------------------------------------------
// own methods
//--------------------------------------------------------------------------

//virtual
void SAL_CALL DynamicResultSetWrapper
	::impl_disposing( const EventObject& )
	throw( RuntimeException )
{
	impl_EnsureNotDisposed();

	osl::Guard< osl::Mutex > aGuard( m_aMutex );

	if( !m_xSource.is() )
		return;

	//release all references to the broadcaster:
	m_xSource.clear();
	m_xSourceResultOne.clear();//?? or only when not static??
	m_xSourceResultTwo.clear();//??
	//@todo m_xMyResultOne.clear(); ???
	//@todo m_xMyResultTwo.clear(); ???
}

//virtual
void SAL_CALL DynamicResultSetWrapper
	::impl_notify( const ListEvent& Changes )
	throw( RuntimeException )
{
	impl_EnsureNotDisposed();
	//@todo
	/*
	<p>The Listener is allowed to blockade this call, until he really want to go
	to the new version.	The only situation, where the listener has to return the
	update call at once is, while he disposes his broadcaster or while he is
	removing himsef as listener (otherwise you deadlock)!!!
	*/
	// handle the actions in the list

	ListEvent aNewEvent;
	aNewEvent.Source = static_cast< XDynamicResultSet * >( this );
	aNewEvent.Changes = Changes.Changes;

	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		for( long i=0; !m_bGotWelcome && i<Changes.Changes.getLength(); i++ )
		{
			ListAction& rAction = aNewEvent.Changes[i];
			switch( rAction.ListActionType )
			{
				case ListActionType::WELCOME:
				{
					WelcomeDynamicResultSetStruct aWelcome;
					if( rAction.ActionInfo >>= aWelcome )
					{
						impl_InitResultSetOne( aWelcome.Old );
						impl_InitResultSetTwo( aWelcome.New );
						m_bGotWelcome = sal_True;

						aWelcome.Old = m_xMyResultOne;
						aWelcome.New = m_xMyResultTwo;

						 rAction.ActionInfo <<= aWelcome;
					}
					else
					{
						OSL_ENSURE( sal_False, "ListActionType was WELCOME but ActionInfo didn't contain a WelcomeDynamicResultSetStruct" );
						//throw RuntimeException();
					}
					break;
				}
			}
		}
		OSL_ENSURE( m_bGotWelcome, "first notification was without WELCOME" );
	}

	if( !m_xListener.is() )
		m_aListenerSet.wait();
	m_xListener->notify( aNewEvent );

	/*
	m_bUseOne = !m_bUseOne;
	if(	m_bUseOne )
		m_xSourceResultCurrent = m_xSourceResultOne;
	else
		m_xSourceResultCurrent = m_xSourceResultTwo;
	*/
}

//--------------------------------------------------------------------------
// XSourceInitialization
//--------------------------------------------------------------------------
//virtual
void SAL_CALL DynamicResultSetWrapper
	::setSource( const Reference< XInterface > & Source )
	throw( AlreadyInitializedException, RuntimeException )
{
	impl_EnsureNotDisposed();
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		if( m_xSource.is() )
		{
			throw AlreadyInitializedException();
		}
	}

	Reference< XDynamicResultSet > xSourceDynamic( Source, UNO_QUERY );
	OSL_ENSURE( xSourceDynamic.is(),
		"the given source is not of required type XDynamicResultSet" );

	Reference< XDynamicResultSetListener > xListener = NULL;
	Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;

	sal_Bool bStatic = sal_False;
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		m_xSource = xSourceDynamic;
		xListener = m_xListener;
		bStatic = m_bStatic;
		xMyListenerImpl = m_xMyListenerImpl;
	}
	if( xListener.is() )
		xSourceDynamic->setListener( m_xMyListenerImpl );
	else if( bStatic )
	{
		Reference< XComponent > xSourceComponent( Source, UNO_QUERY );
		xSourceComponent->addEventListener( Reference< XEventListener > ::query( xMyListenerImpl ) );
	}
	m_aSourceSet.set();
}

//--------------------------------------------------------------------------
// XDynamicResultSet
//--------------------------------------------------------------------------
//virtual
Reference< XResultSet > SAL_CALL DynamicResultSetWrapper
	::getStaticResultSet()
	throw( ListenerAlreadySetException, RuntimeException )
{
	impl_EnsureNotDisposed();

	Reference< XDynamicResultSet > xSource = NULL;
	Reference< XEventListener > xMyListenerImpl = NULL;
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		if( m_xListener.is() )
			throw ListenerAlreadySetException();

		xSource = m_xSource;
		m_bStatic = sal_True;
		xMyListenerImpl = Reference< XEventListener > ::query( m_xMyListenerImpl );
	}

	if( xSource.is() )
	{
		Reference< XComponent > xSourceComponent( xSource, UNO_QUERY );
		xSourceComponent->addEventListener( xMyListenerImpl );
	}
	if( !xSource.is() )
		m_aSourceSet.wait();


	Reference< XResultSet > xResultSet = xSource->getStaticResultSet();
	impl_InitResultSetOne( xResultSet );
	return m_xMyResultOne;
}

//virtual
void SAL_CALL DynamicResultSetWrapper
	::setListener( const Reference<
	XDynamicResultSetListener > & Listener )
	throw( ListenerAlreadySetException, RuntimeException )
{
	impl_EnsureNotDisposed();

	Reference< XDynamicResultSet > xSource = NULL;
	Reference< XDynamicResultSetListener > xMyListenerImpl = NULL;
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		if( m_xListener.is() )
			throw ListenerAlreadySetException();
		if( m_bStatic )
			throw ListenerAlreadySetException();

		m_xListener = Listener;
		addEventListener( Reference< XEventListener >::query( Listener ) );

		xSource = m_xSource;
		xMyListenerImpl = m_xMyListenerImpl;
	}
	if ( xSource.is() )
		xSource->setListener( xMyListenerImpl );

	m_aListenerSet.set();
}

//virtual
void SAL_CALL DynamicResultSetWrapper
	::connectToCache( const Reference< XDynamicResultSet > & xCache )
	throw( ListenerAlreadySetException, AlreadyInitializedException, ServiceNotFoundException, RuntimeException )
{
	impl_EnsureNotDisposed();

	if( m_xListener.is() )
		throw ListenerAlreadySetException();
	if( m_bStatic )
		throw ListenerAlreadySetException();

	Reference< XSourceInitialization > xTarget( xCache, UNO_QUERY );
	OSL_ENSURE( xTarget.is(), "The given Target dosn't have the required interface 'XSourceInitialization'" );
	if( xTarget.is() && m_xSMgr.is() )
	{
		//@todo m_aSourceSet.wait();?

		Reference< XCachedDynamicResultSetStubFactory > xStubFactory;
		try
		{
			xStubFactory = Reference< XCachedDynamicResultSetStubFactory >(
				m_xSMgr->createInstance(
					OUString::createFromAscii(
						"com.sun.star.ucb.CachedDynamicResultSetStubFactory" ) ),
				UNO_QUERY );
		}
		catch ( Exception const & )
		{
		}

		if( xStubFactory.is() )
		{
			xStubFactory->connectToCache(
				  this, xCache, Sequence< NumberedSortingInfo > (), NULL );
			return;
		}
	}
	OSL_ENSURE( sal_False, "could not connect to cache" );
	throw ServiceNotFoundException();
}

//virtual
sal_Int16 SAL_CALL DynamicResultSetWrapper
	::getCapabilities()
	throw( RuntimeException )
{
	impl_EnsureNotDisposed();

	m_aSourceSet.wait();
	Reference< XDynamicResultSet > xSource = NULL;
	{
		osl::Guard< osl::Mutex > aGuard( m_aMutex );
		xSource = m_xSource;
	}
	return xSource->getCapabilities();
}

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// class DynamicResultSetWrapperListener
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

DynamicResultSetWrapperListener::DynamicResultSetWrapperListener(
		DynamicResultSetWrapper* pOwner )
		: m_pOwner( pOwner )
{

}

DynamicResultSetWrapperListener::~DynamicResultSetWrapperListener()
{

}

//--------------------------------------------------------------------------
// XInterface methods.
//--------------------------------------------------------------------------
//list all interfaces inclusive baseclasses of interfaces
XINTERFACE_IMPL_2( DynamicResultSetWrapperListener
				   , XDynamicResultSetListener
				   , XEventListener //base of XDynamicResultSetListener
				   );

//--------------------------------------------------------------------------
// XDynamicResultSetListener methods:
//--------------------------------------------------------------------------
//virtual
void SAL_CALL DynamicResultSetWrapperListener
	::disposing( const EventObject& rEventObject )
	throw( RuntimeException )
{
	osl::Guard< osl::Mutex > aGuard( m_aMutex );

	if( m_pOwner )
		m_pOwner->impl_disposing( rEventObject );
}

//virtual
void SAL_CALL DynamicResultSetWrapperListener
	::notify( const ListEvent& Changes )
	throw( RuntimeException )
{
	osl::Guard< osl::Mutex > aGuard( m_aMutex );

	if( m_pOwner )
		m_pOwner->impl_notify( Changes );
}

//--------------------------------------------------------------------------
// own methods:
//--------------------------------------------------------------------------

void SAL_CALL DynamicResultSetWrapperListener
	::impl_OwnerDies()
{
	osl::Guard< osl::Mutex > aGuard( m_aMutex );

	m_pOwner = NULL;
}

