/**************************************************************
 *
 * 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"
#include "mysql/YDriver.hxx"
#include "mysql/YCatalog.hxx"
#include <osl/diagnose.h>
#include <comphelper/namedvaluecollection.hxx>
#include "connectivity/dbexception.hxx"
#include <connectivity/dbcharset.hxx>
#include <com/sun/star/sdbc/XDriverAccess.hpp>
#include "TConnection.hxx"
#include "resource/common_res.hrc"
#include "resource/sharedresources.hxx"

//........................................................................
namespace connectivity
{
//........................................................................
	using namespace mysql;
	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::sdbc;
	using namespace ::com::sun::star::sdbcx;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::lang;

	namespace mysql
	{
		Reference< XInterface >  SAL_CALL ODriverDelegator_CreateInstance(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFac) throw( Exception )
		{
			return *(new ODriverDelegator(_rxFac));
		}
	}


	//====================================================================
	//= ODriverDelegator
	//====================================================================
	//--------------------------------------------------------------------
	ODriverDelegator::ODriverDelegator(const Reference< XMultiServiceFactory >& _rxFactory)
		: ODriverDelegator_BASE(m_aMutex)
		,m_xFactory(_rxFactory)
		,m_eDriverType(D_ODBC)
	{
	}

	//--------------------------------------------------------------------
	ODriverDelegator::~ODriverDelegator()
	{
		try
		{
			::comphelper::disposeComponent(m_xODBCDriver);
            ::comphelper::disposeComponent(m_xNativeDriver);
			TJDBCDrivers::iterator aIter = m_aJdbcDrivers.begin();
			TJDBCDrivers::iterator aEnd = m_aJdbcDrivers.end();
			for ( ;aIter != aEnd;++aIter )
				::comphelper::disposeComponent(aIter->second);
		}
		catch(const Exception&)
		{
		}
	}

	// --------------------------------------------------------------------------------
	void ODriverDelegator::disposing()
	{
		::osl::MutexGuard aGuard(m_aMutex);


		for (TWeakPairVector::iterator i = m_aConnections.begin(); m_aConnections.end() != i; ++i)
		{
			Reference<XInterface > xTemp = i->first.get();
			::comphelper::disposeComponent(xTemp);
		}
		m_aConnections.clear();
		TWeakPairVector().swap(m_aConnections);

		ODriverDelegator_BASE::disposing();
	}

	namespace
	{
		sal_Bool isOdbcUrl(const ::rtl::OUString& _sUrl)
		{
			return _sUrl.copy(0,16).equalsAscii("sdbc:mysql:odbc:");
		}
        //--------------------------------------------------------------------
        sal_Bool isNativeUrl(const ::rtl::OUString& _sUrl)
		{
            return (!_sUrl.compareTo(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdbc:mysql:mysqlc:")), sizeof("sdbc:mysql:mysqlc:")-1));
		}
        //--------------------------------------------------------------------
        T_DRIVERTYPE lcl_getDriverType(const ::rtl::OUString& _sUrl)
        {
            T_DRIVERTYPE eRet = D_JDBC;
            if ( isOdbcUrl(_sUrl ) )
                eRet = D_ODBC;
            else if ( isNativeUrl(_sUrl ) )
                eRet = D_NATIVE;
            return eRet;
        }
		//--------------------------------------------------------------------
		::rtl::OUString transformUrl(const ::rtl::OUString& _sUrl)
		{
			::rtl::OUString sNewUrl = _sUrl.copy(11);
			if ( isOdbcUrl( _sUrl ) )
				sNewUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdbc:")) + sNewUrl;
            else if ( isNativeUrl( _sUrl ) )
                sNewUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sdbc:")) + sNewUrl;
			else
			{
				sNewUrl = sNewUrl.copy(5);

				::rtl::OUString sTempUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("jdbc:mysql://"));

				sTempUrl += sNewUrl;
				sNewUrl = sTempUrl;
			}
			return sNewUrl;
		}
		//--------------------------------------------------------------------
		Reference< XDriver > lcl_loadDriver(const Reference< XMultiServiceFactory >& _rxFactory,const ::rtl::OUString& _sUrl)
		{
			Reference<XDriverAccess> xDriverAccess(_rxFactory->createInstance(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdbc.DriverManager")) ),UNO_QUERY);
			OSL_ENSURE(xDriverAccess.is(),"Could not load driver manager!");
			Reference< XDriver > xDriver;
			if ( xDriverAccess.is() )
				xDriver = xDriverAccess->getDriverByURL(_sUrl);
			return xDriver;
		}
		//--------------------------------------------------------------------
		Sequence< PropertyValue > lcl_convertProperties(T_DRIVERTYPE _eType,const Sequence< PropertyValue >& info,const ::rtl::OUString& _sUrl)
		{
			::std::vector<PropertyValue> aProps;
			const PropertyValue* pSupported = info.getConstArray();
			const PropertyValue* pEnd = pSupported + info.getLength();

			aProps.reserve(info.getLength() + 5);
			for (;pSupported != pEnd; ++pSupported)
			{
				aProps.push_back( *pSupported );
			}

			if ( _eType == D_ODBC )
			{
				aProps.push_back( PropertyValue(
									::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Silent"))
									,0
									,makeAny(sal_True)
									,PropertyState_DIRECT_VALUE) );
				aProps.push_back( PropertyValue(
									::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PreventGetVersionColumns"))
									,0
									,makeAny(sal_True)
									,PropertyState_DIRECT_VALUE) );
			}
			else if ( _eType == D_JDBC )
			{
				aProps.push_back( PropertyValue(
									::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JavaDriverClass"))
									,0
									,makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.mysql.jdbc.Driver")))
									,PropertyState_DIRECT_VALUE) );
			}
            else
            {
                aProps.push_back( PropertyValue(
									::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PublicConnectionURL"))
									,0
									,makeAny(_sUrl)
									,PropertyState_DIRECT_VALUE) );
            }
			aProps.push_back( PropertyValue(
								::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IsAutoRetrievingEnabled"))
								,0
								,makeAny(sal_True)
								,PropertyState_DIRECT_VALUE) );
			aProps.push_back( PropertyValue(
								::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AutoRetrievingStatement"))
								,0
								,makeAny(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT LAST_INSERT_ID()")))
								,PropertyState_DIRECT_VALUE) );
			aProps.push_back( PropertyValue(
								::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParameterNameSubstitution"))
								,0
								,makeAny(sal_True)
								,PropertyState_DIRECT_VALUE) );
			PropertyValue* pProps = aProps.empty() ? 0 : &aProps[0];
			return Sequence< PropertyValue >(pProps, aProps.size());
		}
	}
	//--------------------------------------------------------------------
	Reference< XDriver > ODriverDelegator::loadDriver( const ::rtl::OUString& url, const Sequence< PropertyValue >& info )
	{
		Reference< XDriver > xDriver;
		const ::rtl::OUString sCuttedUrl = transformUrl(url);
        const T_DRIVERTYPE eType = lcl_getDriverType( url );
		if ( eType == D_ODBC )
		{
			if ( !m_xODBCDriver.is() )
				m_xODBCDriver = lcl_loadDriver(m_xFactory,sCuttedUrl);
			xDriver = m_xODBCDriver;
		} // if ( bIsODBC )
        else if ( eType == D_NATIVE )
		{
			if ( !m_xNativeDriver.is() )
				m_xNativeDriver = lcl_loadDriver(m_xFactory,sCuttedUrl);
			xDriver = m_xNativeDriver;
		}
		else
		{
            ::comphelper::NamedValueCollection aSettings( info );
            ::rtl::OUString sDriverClass(RTL_CONSTASCII_USTRINGPARAM("com.mysql.jdbc.Driver"));
            sDriverClass = aSettings.getOrDefault( "JavaDriverClass", sDriverClass );

			TJDBCDrivers::iterator aFind = m_aJdbcDrivers.find(sDriverClass);
			if ( aFind == m_aJdbcDrivers.end() )
				aFind = m_aJdbcDrivers.insert(TJDBCDrivers::value_type(sDriverClass,lcl_loadDriver(m_xFactory,sCuttedUrl))).first;
			xDriver = aFind->second;
		}

		return xDriver;
	}

	//--------------------------------------------------------------------
	Reference< XConnection > SAL_CALL ODriverDelegator::connect( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException)
	{
		Reference< XConnection > xConnection;
		if ( acceptsURL(url) )
		{
			Reference< XDriver > xDriver;
			xDriver = loadDriver(url,info);
			if ( xDriver.is() )
			{
				::rtl::OUString sCuttedUrl = transformUrl(url);
                const T_DRIVERTYPE eType = lcl_getDriverType( url );
				Sequence< PropertyValue > aConvertedProperties = lcl_convertProperties(eType,info,url);
                if ( eType == D_JDBC )
                {
                    ::comphelper::NamedValueCollection aSettings( info );
                    ::rtl::OUString sIanaName = aSettings.getOrDefault( "CharSet", ::rtl::OUString() );
                    if ( sIanaName.getLength() )
                    {
                        ::dbtools::OCharsetMap aLookupIanaName;
			            ::dbtools::OCharsetMap::const_iterator aLookup = aLookupIanaName.find(sIanaName, ::dbtools::OCharsetMap::IANA());
			            if (aLookup != aLookupIanaName.end() )
                        {
                            ::rtl::OUString sAdd;
                            if ( RTL_TEXTENCODING_UTF8 == (*aLookup).getEncoding() )
                            {
                                static const ::rtl::OUString s_sCharSetOp(RTL_CONSTASCII_USTRINGPARAM("useUnicode=true&"));
                                if ( !sCuttedUrl.matchIgnoreAsciiCase(s_sCharSetOp) )
                                {
                                    sAdd = s_sCharSetOp;
                                } // if ( !sCuttedUrl.matchIgnoreAsciiCase(s_sCharSetOp) )
                            } // if ( RTL_TEXTENCODING_UTF8 == (*aLookup).getEncoding() )
                            if ( sCuttedUrl.indexOf('?') == -1 )
                                sCuttedUrl += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("?"));
                            else
                                sCuttedUrl += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("&"));
                            sCuttedUrl += sAdd;
                            sCuttedUrl += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("characterEncoding="));
                            sCuttedUrl += sIanaName;
                        }
                    }
                } // if ( !bIsODBC )

				xConnection = xDriver->connect( sCuttedUrl, aConvertedProperties );
				if ( xConnection.is() )
				{
					OMetaConnection* pMetaConnection = NULL;
					// now we have to set the URL to get the correct answer for metadata()->getURL()
					Reference< XUnoTunnel> xTunnel(xConnection,UNO_QUERY);
					if ( xTunnel.is() )
					{
						pMetaConnection = reinterpret_cast<OMetaConnection*>(xTunnel->getSomething( OMetaConnection::getUnoTunnelImplementationId() ));
						if ( pMetaConnection )
							pMetaConnection->setURL(url);
					}
					m_aConnections.push_back(TWeakPair(WeakReferenceHelper(xConnection),TWeakConnectionPair(WeakReferenceHelper(),pMetaConnection)));
				}
			}
		}
		return xConnection;
	}

	//--------------------------------------------------------------------
	sal_Bool SAL_CALL ODriverDelegator::acceptsURL( const ::rtl::OUString& url ) throw (SQLException, RuntimeException)
	{
		Sequence< PropertyValue > info;

        sal_Bool bOK =  url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "sdbc:mysql:odbc:" ) )
                    ||  url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "sdbc:mysql:jdbc:" ) )
                    ||  (   url.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "sdbc:mysql:mysqlc:" ) )
                        &&  loadDriver( url, info ).is()
                        );
		return bOK;
	}

	//--------------------------------------------------------------------
	Sequence< DriverPropertyInfo > SAL_CALL ODriverDelegator::getPropertyInfo( const ::rtl::OUString& url, const Sequence< PropertyValue >& /*info*/ ) throw (SQLException, RuntimeException)
	{
		::std::vector< DriverPropertyInfo > aDriverInfo;
		if ( !acceptsURL(url) )
            return Sequence< DriverPropertyInfo >();

		Sequence< ::rtl::OUString > aBoolean(2);
		aBoolean[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0"));
		aBoolean[1] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("1"));


		aDriverInfo.push_back(DriverPropertyInfo(
				::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharSet"))
				,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("CharSet of the database."))
				,sal_False
				,::rtl::OUString()
				,Sequence< ::rtl::OUString >())
				);
		aDriverInfo.push_back(DriverPropertyInfo(
				::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SuppressVersionColumns"))
				,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Display version columns (when available)."))
				,sal_False
				,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0"))
				,aBoolean)
				);
        const T_DRIVERTYPE eType = lcl_getDriverType( url );
		if ( eType == D_JDBC )
		{
			aDriverInfo.push_back(DriverPropertyInfo(
					::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JavaDriverClass"))
					,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("The JDBC driver class name."))
					,sal_True
					,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.mysql.jdbc.Driver"))
					,Sequence< ::rtl::OUString >())
					);
		}
		else if ( eType == D_NATIVE )
        {
            aDriverInfo.push_back(DriverPropertyInfo(
                    ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LocalSocket"))
                    ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
                        "The file path of a socket to connect to a local MySQL server."))
                    ,sal_False
                    ,::rtl::OUString()
                    ,Sequence< ::rtl::OUString >())
                    );
            aDriverInfo.push_back(DriverPropertyInfo(
                    ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NamedPipe"))
                    ,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
                        "The name of a pipe to connect to a local MySQL server."))
                    ,sal_False
                    ,::rtl::OUString()
                    ,Sequence< ::rtl::OUString >())
                    );
        }

        return Sequence< DriverPropertyInfo >(&aDriverInfo[0],aDriverInfo.size());
	}

	//--------------------------------------------------------------------
	sal_Int32 SAL_CALL ODriverDelegator::getMajorVersion(  ) throw (RuntimeException)
	{
		return 1;
	}

	//--------------------------------------------------------------------
	sal_Int32 SAL_CALL ODriverDelegator::getMinorVersion(  ) throw (RuntimeException)
	{
		return 0;
	}

	//--------------------------------------------------------------------
	Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByConnection( const Reference< XConnection >& connection ) throw (SQLException, RuntimeException)
	{
		::osl::MutexGuard aGuard( m_aMutex );
		checkDisposed(ODriverDelegator_BASE::rBHelper.bDisposed);

		Reference< XTablesSupplier > xTab;
		Reference< XUnoTunnel> xTunnel(connection,UNO_QUERY);
		if ( xTunnel.is() )
		{
			OMetaConnection* pConnection = reinterpret_cast<OMetaConnection*>(xTunnel->getSomething( OMetaConnection::getUnoTunnelImplementationId() ));
			if ( pConnection )
			{
				TWeakPairVector::iterator aEnd = m_aConnections.end();
				for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
				{
					if ( i->second.second == pConnection )
					{
						xTab = Reference< XTablesSupplier >(i->second.first.get().get(),UNO_QUERY);
						if ( !xTab.is() )
						{
							xTab = new OMySQLCatalog(connection);
							i->second.first = WeakReferenceHelper(xTab);
						}
						break;
					}
				}
			}
        } // if ( xTunnel.is() )
        if ( !xTab.is() )
        {
            TWeakPairVector::iterator aEnd = m_aConnections.end();
            for (TWeakPairVector::iterator i = m_aConnections.begin(); aEnd != i; ++i)
            {
                Reference< XConnection > xTemp(i->first.get(),UNO_QUERY);
                if ( xTemp == connection )
                {
                    xTab = Reference< XTablesSupplier >(i->second.first.get().get(),UNO_QUERY);
                    if ( !xTab.is() )
                    {
                        xTab = new OMySQLCatalog(connection);
                        i->second.first = WeakReferenceHelper(xTab);
                    }
                    break;
                }
            }
        }
		return xTab;
	}

	//--------------------------------------------------------------------
	Reference< XTablesSupplier > SAL_CALL ODriverDelegator::getDataDefinitionByURL( const ::rtl::OUString& url, const Sequence< PropertyValue >& info ) throw (SQLException, RuntimeException)
	{
		if ( ! acceptsURL(url) )
        {
            ::connectivity::SharedResources aResources;
            const ::rtl::OUString sMessage = aResources.getResourceString(STR_URI_SYNTAX_ERROR);
            ::dbtools::throwGenericSQLException(sMessage ,*this);
        } // if ( ! acceptsURL(url) )

		return getDataDefinitionByConnection(connect(url,info));
	}

	// XServiceInfo
	// --------------------------------------------------------------------------------
	//------------------------------------------------------------------------------
	rtl::OUString ODriverDelegator::getImplementationName_Static(  ) throw(RuntimeException)
	{
		return rtl::OUString::createFromAscii("org.openoffice.comp.drivers.MySQL.Driver");
	}
	//------------------------------------------------------------------------------
	Sequence< ::rtl::OUString > ODriverDelegator::getSupportedServiceNames_Static(  ) throw (RuntimeException)
	{
		Sequence< ::rtl::OUString > aSNS( 2 );
		aSNS[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdbc.Driver");
		aSNS[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdbcx.Driver");
		return aSNS;
	}
	//------------------------------------------------------------------
	::rtl::OUString SAL_CALL ODriverDelegator::getImplementationName(  ) throw(RuntimeException)
	{
		return getImplementationName_Static();
	}

	//------------------------------------------------------------------
	sal_Bool SAL_CALL ODriverDelegator::supportsService( const ::rtl::OUString& _rServiceName ) throw(RuntimeException)
	{
		Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
		const ::rtl::OUString* pSupported = aSupported.getConstArray();
		const ::rtl::OUString* pEnd = pSupported + aSupported.getLength();
		for (;pSupported != pEnd && !pSupported->equals(_rServiceName); ++pSupported)
			;

		return pSupported != pEnd;
	}
	//------------------------------------------------------------------
	Sequence< ::rtl::OUString > SAL_CALL ODriverDelegator::getSupportedServiceNames(  ) throw(RuntimeException)
	{
		return getSupportedServiceNames_Static();
	}
	//------------------------------------------------------------------
//........................................................................
}	// namespace connectivity
//........................................................................
