/**************************************************************
 * 
 * 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_connectivity.hxx"
#ifndef _CONNECTIVITY_CONNECTIONWRAPPER_HXX_
#include "connectivity/ConnectionWrapper.hxx"
#endif
#include <com/sun/star/sdbc/ColumnValue.hpp>
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <comphelper/uno3.hxx>
#include <comphelper/sequence.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <com/sun/star/reflection/XProxyFactory.hpp>
#include <rtl/digest.h>
#include <algorithm>

#include <algorithm>

using namespace connectivity;
//------------------------------------------------------------------------------
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::sdbc;
using namespace ::com::sun::star::reflection;
// --------------------------------------------------------------------------------
OConnectionWrapper::OConnectionWrapper()
{

}
// -----------------------------------------------------------------------------
void OConnectionWrapper::setDelegation(Reference< XAggregation >& _rxProxyConnection,oslInterlockedCount& _rRefCount)
{
	OSL_ENSURE(_rxProxyConnection.is(),"OConnectionWrapper: Connection must be valid!");
	osl_incrementInterlockedCount( &_rRefCount );
	if (_rxProxyConnection.is())
	{
		// transfer the (one and only) real ref to the aggregate to our member
		m_xProxyConnection = _rxProxyConnection;
		_rxProxyConnection = NULL;
		::comphelper::query_aggregation(m_xProxyConnection,m_xConnection);
		m_xTypeProvider.set(m_xConnection,UNO_QUERY);
		m_xUnoTunnel.set(m_xConnection,UNO_QUERY);
		m_xServiceInfo.set(m_xConnection,UNO_QUERY);

		// set ourself as delegator
		Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this );
		m_xProxyConnection->setDelegator( xIf );

	}
	osl_decrementInterlockedCount( &_rRefCount );
}
// -----------------------------------------------------------------------------
void OConnectionWrapper::setDelegation(const Reference< XConnection >& _xConnection
									   ,const Reference< XMultiServiceFactory>& _xORB
									   ,oslInterlockedCount& _rRefCount)
{
	OSL_ENSURE(_xConnection.is(),"OConnectionWrapper: Connection must be valid!");
	osl_incrementInterlockedCount( &_rRefCount );

	m_xConnection = _xConnection;
	m_xTypeProvider.set(m_xConnection,UNO_QUERY);
	m_xUnoTunnel.set(m_xConnection,UNO_QUERY);
	m_xServiceInfo.set(m_xConnection,UNO_QUERY);

	Reference< XProxyFactory >	xProxyFactory(_xORB->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.ProxyFactory"))),UNO_QUERY);
	Reference< XAggregation > xConProxy = xProxyFactory->createProxy(_xConnection);
	if (xConProxy.is())
	{
		// transfer the (one and only) real ref to the aggregate to our member
		m_xProxyConnection = xConProxy;

		// set ourself as delegator
		Reference<XInterface> xIf = static_cast< XUnoTunnel* >( this );
		m_xProxyConnection->setDelegator( xIf );

	}
	osl_decrementInterlockedCount( &_rRefCount );
}
// -----------------------------------------------------------------------------
void OConnectionWrapper::disposing()
{
m_xConnection.clear();
}
//-----------------------------------------------------------------------------
OConnectionWrapper::~OConnectionWrapper()
{
	if (m_xProxyConnection.is())
		m_xProxyConnection->setDelegator(NULL);
}

// XServiceInfo
// --------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OConnectionWrapper::getImplementationName(  ) throw (::com::sun::star::uno::RuntimeException)
{
	return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.drivers.OConnectionWrapper" ) );
}

// --------------------------------------------------------------------------------
::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL OConnectionWrapper::getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException)
{
	// first collect the services which are supported by our aggregate
	Sequence< ::rtl::OUString > aSupported;
	if ( m_xServiceInfo.is() )
		aSupported = m_xServiceInfo->getSupportedServiceNames();

	// append our own service, if necessary
	::rtl::OUString sConnectionService( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdbc.Connection" ) );
	if ( 0 == ::comphelper::findValue( aSupported, sConnectionService, sal_True ).getLength() )
	{
		sal_Int32 nLen = aSupported.getLength();
		aSupported.realloc( nLen + 1 );
		aSupported[ nLen ] = sConnectionService;
	}

	// outta here
	return aSupported;
}

// --------------------------------------------------------------------------------
sal_Bool SAL_CALL OConnectionWrapper::supportsService( const ::rtl::OUString& _rServiceName ) throw(::com::sun::star::uno::RuntimeException)
{
	return ::comphelper::findValue( getSupportedServiceNames(), _rServiceName, sal_True ).getLength() != 0;
}

// --------------------------------------------------------------------------------
Any SAL_CALL OConnectionWrapper::queryInterface( const Type& _rType ) throw (RuntimeException)
{
	Any aReturn = OConnection_BASE::queryInterface(_rType);
	return aReturn.hasValue() ? aReturn : (m_xProxyConnection.is() ? m_xProxyConnection->queryAggregation(_rType) : aReturn);
}
// --------------------------------------------------------------------------------
Sequence< Type > SAL_CALL OConnectionWrapper::getTypes(  ) throw (::com::sun::star::uno::RuntimeException)
{
	return ::comphelper::concatSequences(
		OConnection_BASE::getTypes(),
		m_xTypeProvider->getTypes()
	);
}
// -----------------------------------------------------------------------------
// com::sun::star::lang::XUnoTunnel
sal_Int64 SAL_CALL OConnectionWrapper::getSomething( const Sequence< sal_Int8 >& rId ) throw(RuntimeException)
{
	if (rId.getLength() == 16 && 0 == rtl_compareMemory(getUnoTunnelImplementationId().getConstArray(),  rId.getConstArray(), 16 ) )
		return reinterpret_cast< sal_Int64 >( this );

	if(m_xUnoTunnel.is())
		return m_xUnoTunnel->getSomething(rId);
	return 0;
}

// -----------------------------------------------------------------------------
Sequence< sal_Int8 > OConnectionWrapper::getUnoTunnelImplementationId()
{
	static ::cppu::OImplementationId * pId = 0;
	if (! pId)
	{
		::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
		if (! pId)
		{
			static ::cppu::OImplementationId aId;
			pId = &aId;
		}
	}
	return pId->getImplementationId();
}
// -----------------------------------------------------------------------------
namespace
{
	class TPropertyValueLessFunctor : public ::std::binary_function< ::com::sun::star::beans::PropertyValue,::com::sun::star::beans::PropertyValue,bool>
	{
	public:
		TPropertyValueLessFunctor()
		{}
		bool operator() (const ::com::sun::star::beans::PropertyValue& lhs, const ::com::sun::star::beans::PropertyValue& rhs) const
		{
			const rtl_uString* l = lhs.Name.pData;
			const rtl_uString* r = rhs.Name.pData;
			const int c = rtl_ustr_compareIgnoreAsciiCase_WithLength( l->buffer, l->length, r->buffer, r->length );
			return (c < 0);
		}
	};

}

// -----------------------------------------------------------------------------
// creates a unique id out of the url and sequence of properties
void OConnectionWrapper::createUniqueId( const ::rtl::OUString& _rURL
					,Sequence< PropertyValue >& _rInfo
					,sal_uInt8* _pBuffer
					,const ::rtl::OUString& _rUserName
					,const ::rtl::OUString& _rPassword)
{
	// first we create the digest we want to have
	rtlDigest aDigest = rtl_digest_create( rtl_Digest_AlgorithmSHA1 );
	rtlDigestError aError = rtl_digest_update(aDigest,_rURL.getStr(),_rURL.getLength()*sizeof(sal_Unicode));
	if ( _rUserName.getLength() )
		aError = rtl_digest_update(aDigest,_rUserName.getStr(),_rUserName.getLength()*sizeof(sal_Unicode));
	if ( _rPassword.getLength() )
		aError = rtl_digest_update(aDigest,_rPassword.getStr(),_rPassword.getLength()*sizeof(sal_Unicode));
	// now we need to sort the properties
	PropertyValue* pBegin = _rInfo.getArray();
	PropertyValue* pEnd   = pBegin + _rInfo.getLength();
	::std::sort(pBegin,pEnd,TPropertyValueLessFunctor());

	pBegin = _rInfo.getArray();
	pEnd   = pBegin + _rInfo.getLength();
	for (; pBegin != pEnd; ++pBegin)
	{
		// we only include strings an integer values
		::rtl::OUString sValue;
		if ( pBegin->Value >>= sValue )
			;
		else
		{
			sal_Int32 nValue = 0;
			if ( pBegin->Value >>= nValue )
				sValue = ::rtl::OUString::valueOf(nValue);
			else
			{
				Sequence< ::rtl::OUString> aSeq;
				if ( pBegin->Value >>= aSeq )
				{
					const ::rtl::OUString* pSBegin = aSeq.getConstArray();
					const ::rtl::OUString* pSEnd   = pSBegin + aSeq.getLength();
					for(;pSBegin != pSEnd;++pSBegin)
						aError = rtl_digest_update(aDigest,pSBegin->getStr(),pSBegin->getLength()*sizeof(sal_Unicode));
				}
			}
		}
		if ( sValue.getLength() > 0 )
		{
			// we don't have to convert this into UTF8 because we don't store on a file system
			aError = rtl_digest_update(aDigest,sValue.getStr(),sValue.getLength()*sizeof(sal_Unicode));
		}
	}

	aError = rtl_digest_get(aDigest,_pBuffer,RTL_DIGEST_LENGTH_SHA1);
	// we have to destroy the digest
	rtl_digest_destroy(aDigest);
}
// -----------------------------------------------------------------------------


