/**************************************************************
 * 
 * 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_dbui.hxx"
#include "RTableConnectionData.hxx"
#include <tools/debug.hxx>
#include <com/sun/star/sdbc/KeyRule.hpp>
#include <com/sun/star/sdbcx/KeyType.hpp>
#include <com/sun/star/sdbcx/XKeysSupplier.hpp>
#include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp>
#include <com/sun/star/sdbcx/XAppend.hpp>
#include <com/sun/star/sdbcx/XDrop.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include "dbustrings.hrc"
#include "dbu_rel.hrc"
#include "UITools.hxx"
#include "moduledbu.hxx"
#include <connectivity/dbexception.hxx>
#include <connectivity/dbtools.hxx>

using namespace dbaui;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::lang;

DBG_NAME(ORelationTableConnectionData)
//========================================================================
// class ORelationTableConnectionData
//========================================================================
//------------------------------------------------------------------------
ORelationTableConnectionData::ORelationTableConnectionData()
	:OTableConnectionData()
	,m_nUpdateRules(KeyRule::NO_ACTION)
	,m_nDeleteRules(KeyRule::NO_ACTION)
	,m_nCardinality(CARDINAL_UNDEFINED)
{
	DBG_CTOR(ORelationTableConnectionData,NULL);
}
//------------------------------------------------------------------------
ORelationTableConnectionData::ORelationTableConnectionData( const TTableWindowData::value_type& _pReferencingTable,
                                                            const TTableWindowData::value_type& _pReferencedTable,
															const ::rtl::OUString& rConnName )
    :OTableConnectionData( _pReferencingTable, _pReferencedTable )
    ,m_nUpdateRules(KeyRule::NO_ACTION)
    ,m_nDeleteRules(KeyRule::NO_ACTION)
    ,m_nCardinality(CARDINAL_UNDEFINED)
{
	DBG_CTOR(ORelationTableConnectionData,NULL);
    m_aConnName = rConnName;
	
    if ( m_aConnName.Len() )
	    SetCardinality();
}

//------------------------------------------------------------------------
ORelationTableConnectionData::ORelationTableConnectionData( const ORelationTableConnectionData& rConnData )
	:OTableConnectionData( rConnData )
{
	DBG_CTOR(ORelationTableConnectionData,NULL);
	*this = rConnData;
}

//------------------------------------------------------------------------
ORelationTableConnectionData::~ORelationTableConnectionData()
{
	DBG_DTOR(ORelationTableConnectionData,NULL);
}

//------------------------------------------------------------------------
sal_Bool ORelationTableConnectionData::DropRelation()
{
	DBG_CHKTHIS(ORelationTableConnectionData,NULL);
	::osl::MutexGuard aGuard( m_aMutex );
	////////////////////////////////////////////////////////////
	// Relation loeschen
	Reference< XIndexAccess> xKeys = getReferencingTable()->getKeys();
	if( m_aConnName.Len() && xKeys.is() )
	{
        const sal_Int32 nCount = xKeys->getCount();
        for(sal_Int32 i = 0;i < nCount;++i)
		{
            Reference< XPropertySet> xKey(xKeys->getByIndex(i),UNO_QUERY);
			OSL_ENSURE(xKey.is(),"Key is not valid!");
			if(xKey.is())
			{
				::rtl::OUString sName;
				xKey->getPropertyValue(PROPERTY_NAME) >>= sName;
				if(String(sName) == m_aConnName)
				{
					Reference< XDrop> xDrop(xKeys,UNO_QUERY);
					OSL_ENSURE(xDrop.is(),"can't drop key because we haven't a drop interface!");
					if(xDrop.is())
						xDrop->dropByIndex(i);
					break;
				}
			}
		}
	}
	return sal_True;
}

//------------------------------------------------------------------------
void ORelationTableConnectionData::ChangeOrientation()
{
	DBG_CHKTHIS(ORelationTableConnectionData,NULL);
	//////////////////////////////////////////////////////////////////////
	// Source- und DestFieldName der Linien austauschen
	::rtl::OUString sTempString;
	OConnectionLineDataVec::iterator aIter = m_vConnLineData.begin();
    OConnectionLineDataVec::iterator aEnd = m_vConnLineData.end();
	for(;aIter != aEnd;++aIter)
	{
		sTempString = (*aIter)->GetSourceFieldName();
		(*aIter)->SetSourceFieldName( (*aIter)->GetDestFieldName() );
		(*aIter)->SetDestFieldName( sTempString );
	}

	//////////////////////////////////////////////////////////////////////
	// Member anpassen
    TTableWindowData::value_type pTemp = m_pReferencingTable;
    m_pReferencingTable = m_pReferencedTable;
    m_pReferencedTable = pTemp;
}

//------------------------------------------------------------------------
void ORelationTableConnectionData::SetCardinality()
{
	DBG_CHKTHIS(ORelationTableConnectionData,NULL);
	::osl::MutexGuard aGuard( m_aMutex );
	m_nCardinality = CARDINAL_UNDEFINED;

	if( IsSourcePrimKey() )
	{
		if( IsDestPrimKey() )
			m_nCardinality = CARDINAL_ONE_ONE;
		else
			m_nCardinality = CARDINAL_ONE_MANY;
	}

	if( IsDestPrimKey() )
	{
		if( !IsSourcePrimKey() )
			m_nCardinality = CARDINAL_MANY_ONE;
	}

}
// -----------------------------------------------------------------------------
sal_Bool ORelationTableConnectionData::checkPrimaryKey(const Reference< XPropertySet>& i_xTable,EConnectionSide _eEConnectionSide) const
{
	// check if Table has the primary key column dependig on _eEConnectionSide
	sal_uInt16	nPrimKeysCount		= 0,
			nValidLinesCount	= 0;
    const Reference< XNameAccess> xKeyColumns = dbtools::getPrimaryKeyColumns_throw(i_xTable);
	if ( xKeyColumns.is() )
	{
		Sequence< ::rtl::OUString> aKeyColumns = xKeyColumns->getElementNames();
		const ::rtl::OUString* pKeyIter	= aKeyColumns.getConstArray();
		const ::rtl::OUString* pKeyEnd  = pKeyIter + aKeyColumns.getLength();

		for(;pKeyIter != pKeyEnd;++pKeyIter)
		{
			OConnectionLineDataVec::const_iterator aIter = m_vConnLineData.begin();
            OConnectionLineDataVec::const_iterator aEnd = m_vConnLineData.end();
            for(;aIter != aEnd;++aIter)
			{
				++nValidLinesCount;
				if ( (*aIter)->GetFieldName(_eEConnectionSide) == *pKeyIter )
				{
					++nPrimKeysCount;
					break;
				}
			}
		}
        if ( nPrimKeysCount != aKeyColumns.getLength() )
			return sal_False;
	}
	if ( !nPrimKeysCount || nPrimKeysCount != nValidLinesCount )
		return sal_False;

	return sal_True;
}
//------------------------------------------------------------------------
sal_Bool ORelationTableConnectionData::IsConnectionPossible()
{
	DBG_CHKTHIS(ORelationTableConnectionData,NULL);
	::osl::MutexGuard aGuard( m_aMutex );

	//////////////////////////////////////////////////////////////////////
	// Wenn die SourceFelder ein PrimKey sind, ist nur die Orientierung falsch
	if ( IsSourcePrimKey() && !IsDestPrimKey() )
		ChangeOrientation();

	return sal_True;
}

//------------------------------------------------------------------------
OConnectionLineDataRef ORelationTableConnectionData::CreateLineDataObj()
{
	return new OConnectionLineData();
}

//------------------------------------------------------------------------
OConnectionLineDataRef ORelationTableConnectionData::CreateLineDataObj( const OConnectionLineData& rConnLineData )
{
	return new OConnectionLineData( rConnLineData );
}

//------------------------------------------------------------------------
void ORelationTableConnectionData::CopyFrom(const OTableConnectionData& rSource)
{
	// wie in der Basisklasse zurueckziehen auf das (nicht-virtuelle) operator=
	*this = *static_cast<const ORelationTableConnectionData*>(&rSource);
}

//------------------------------------------------------------------------
ORelationTableConnectionData& ORelationTableConnectionData::operator=( const ORelationTableConnectionData& rConnData )
{
	if (&rConnData == this)
		return *this;

	OTableConnectionData::operator=( rConnData );
	m_nUpdateRules = rConnData.GetUpdateRules();
	m_nDeleteRules = rConnData.GetDeleteRules();
	m_nCardinality = rConnData.GetCardinality();

	return *this;
}
namespace dbaui
{
//-------------------------------------------------------------------------
bool operator==(const ORelationTableConnectionData& lhs, const ORelationTableConnectionData& rhs)
{
	bool bEqual = (lhs.m_nUpdateRules == rhs.m_nUpdateRules) 
        && (lhs.m_nDeleteRules == rhs.m_nDeleteRules)
        && (lhs.m_nCardinality == rhs.m_nCardinality)
        && (lhs.getReferencingTable() == rhs.getReferencingTable())
        && (lhs.getReferencedTable() == rhs.getReferencedTable())
        && (lhs.m_aConnName == rhs.m_aConnName)
        && (lhs.m_vConnLineData.size() == rhs.m_vConnLineData.size());
    
    if ( bEqual )
    {
        std::vector< OConnectionLineDataRef >::const_iterator aIter = lhs.m_vConnLineData.begin();
        std::vector< OConnectionLineDataRef >::const_iterator aEnd = lhs.m_vConnLineData.end();
        for (sal_Int32 i = 0; aIter != aEnd; ++aIter,++i)
        {
            if ( *(rhs.m_vConnLineData[i]) != **aIter )
                break;
        }
        bEqual = aIter == aEnd;
    }
    return bEqual;
}
}
//------------------------------------------------------------------------
sal_Bool ORelationTableConnectionData::Update()
{
	::osl::MutexGuard aGuard( m_aMutex );
	////////////////////////////////////////////////////////////
	// Alte Relation loeschen
	{
		DropRelation();
		if( !IsConnectionPossible() )
			return sal_False;
	}

	// reassign the keys because the orientaion could be changed
	Reference<XPropertySet> xTableProp(getReferencingTable()->getTable());
	Reference< XIndexAccess> xKeys ( getReferencingTable()->getKeys());
	
	if ( !xKeys.is() )
		return sal_False;
	////////////////////////////////////////////////////////////
	// Neue Relation erzeugen
	Reference<XDataDescriptorFactory> xKeyFactory(xKeys,UNO_QUERY);
	OSL_ENSURE(xKeyFactory.is(),"No XDataDescriptorFactory Interface!");
	Reference<XAppend> xAppend(xKeyFactory,UNO_QUERY);
	OSL_ENSURE(xAppend.is(),"No XAppend Interface!");

	Reference<XPropertySet> xKey = xKeyFactory->createDataDescriptor();
	OSL_ENSURE(xKey.is(),"Key is null!");
	if ( xKey.is() && xTableProp.is() )
	{
		// build a foreign key name
		::rtl::OUString sSourceName;
        xTableProp->getPropertyValue(PROPERTY_NAME) >>= sSourceName;
		::rtl::OUString sKeyName = sSourceName;
		sKeyName += getReferencedTable()->GetTableName();

		xKey->setPropertyValue(PROPERTY_NAME,makeAny(sKeyName));
		xKey->setPropertyValue(PROPERTY_TYPE,makeAny(KeyType::FOREIGN));
		xKey->setPropertyValue(PROPERTY_REFERENCEDTABLE,makeAny(::rtl::OUString(getReferencedTable()->GetTableName())));
		xKey->setPropertyValue(PROPERTY_UPDATERULE, makeAny(GetUpdateRules()));
		xKey->setPropertyValue(PROPERTY_DELETERULE, makeAny(GetDeleteRules()));
	}

	Reference<XColumnsSupplier> xColSup(xKey,UNO_QUERY);
	if ( xColSup.is() )
	{
		Reference<XNameAccess> xColumns = xColSup->getColumns();
		Reference<XDataDescriptorFactory> xColumnFactory(xColumns,UNO_QUERY);
		Reference<XAppend> xColumnAppend(xColumns,UNO_QUERY);
		if ( xColumnFactory.is() )
		{
			OConnectionLineDataVec::iterator aIter = m_vConnLineData.begin();
            OConnectionLineDataVec::iterator aEnd = m_vConnLineData.end();
	        for(;aIter != aEnd;++aIter)
			{
				if((*aIter)->GetSourceFieldName().getLength() && (*aIter)->GetDestFieldName().getLength())
				{
					Reference<XPropertySet> xColumn;
					xColumn = xColumnFactory->createDataDescriptor();
					if ( xColumn.is() )
					{
						xColumn->setPropertyValue(PROPERTY_NAME,makeAny((*aIter)->GetSourceFieldName()));
						xColumn->setPropertyValue(PROPERTY_RELATEDCOLUMN,makeAny((*aIter)->GetDestFieldName()));
						xColumnAppend->appendByDescriptor(xColumn);
					}
				}
			}
			
			if ( xColumns->hasElements() )
				xAppend->appendByDescriptor(xKey);
		}
		// to get the key we have to reget it because after append it is no longer valid
	}

	// get the name of foreign key // search for columns
	m_aConnName = ::rtl::OUString();
xKey.clear();
    bool bDropRelation = false;
	for(sal_Int32 i=0;i<xKeys->getCount();++i)
	{
		xKeys->getByIndex(i) >>= xKey;
		OSL_ENSURE(xKey.is(),"Key is not valid!");
		if ( xKey.is() )
		{
			sal_Int32 nType = 0;
			xKey->getPropertyValue(PROPERTY_TYPE) >>= nType;
			::rtl::OUString sReferencedTable;
			xKey->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= sReferencedTable;
			if ( sReferencedTable == ::rtl::OUString(getReferencedTable()->GetTableName()) )
			{
                xColSup.set(xKey,UNO_QUERY_THROW);
                try
                {
                    Reference<XNameAccess> xColumns = xColSup->getColumns();
		            Sequence< ::rtl::OUString> aNames = xColumns->getElementNames();
		            const ::rtl::OUString* pIter = aNames.getConstArray();
		            const ::rtl::OUString* pEnd = pIter + aNames.getLength();

                    Reference<XPropertySet> xColumn;
                    ::rtl::OUString sName,sRelatedColumn;
                    for ( ; pIter != pEnd ; ++pIter )
                    {
                        xColumn.set(xColumns->getByName(*pIter),UNO_QUERY_THROW);
                        xColumn->getPropertyValue(PROPERTY_NAME)			>>= sName; 
				        xColumn->getPropertyValue(PROPERTY_RELATEDCOLUMN)	>>= sRelatedColumn;

                        OConnectionLineDataVec::iterator aIter = m_vConnLineData.begin();
                        OConnectionLineDataVec::iterator aEnd = m_vConnLineData.end();
	                    for(;aIter != aEnd;++aIter)
			            {
				            if(    (*aIter)->GetSourceFieldName() == sName 
                                && (*aIter)->GetDestFieldName() == sRelatedColumn )
				            {
				                break;
                            }
                        }
                        if ( aIter == m_vConnLineData.end() )
                            break;
                    }
                    if ( pIter == pEnd )
                    {
                        xKey->getPropertyValue(PROPERTY_NAME) >>= sName;
				        m_aConnName = sName;
                        bDropRelation = aNames.getLength() == 0; // the key contains no column, so it isn't valid and we have to drop it
                        //here we already know our column structure so we don't have to recreate the table connection data
                        xColSup.clear();
                        break;
                    }
                }
                catch(Exception&)
                {                    
                }                
			}
		}
	xKey.clear();
	} // for(sal_Int32 i=0;i<xKeys->getCount();++i)
    if ( bDropRelation )
    {
        DropRelation();
        String sError(ModuleRes(STR_QUERY_REL_COULD_NOT_CREATE));
        ::dbtools::throwGenericSQLException(sError,NULL);
    }

//	OSL_ENSURE(xKey.is(),"No key found have insertion!");

    // The fields the relation marks may not be the same as our LineDatas mark after the relation has been updated
	if ( xColSup.is() )
	{
        OConnectionLineDataVec().swap(m_vConnLineData);
		Reference<XNameAccess> xColumns = xColSup->getColumns();
		Sequence< ::rtl::OUString> aNames = xColumns->getElementNames();
		const ::rtl::OUString* pIter = aNames.getConstArray();
		const ::rtl::OUString* pEnd = pIter + aNames.getLength();

		m_vConnLineData.reserve( aNames.getLength() );
		Reference<XPropertySet> xColumn;
		::rtl::OUString sName,sRelatedColumn;

		for(;pIter != pEnd;++pIter)
		{
			xColumns->getByName(*pIter) >>= xColumn;
			if ( xColumn.is() )
			{
				OConnectionLineDataRef pNewData = CreateLineDataObj();

				xColumn->getPropertyValue(PROPERTY_NAME)			>>= sName; 
				xColumn->getPropertyValue(PROPERTY_RELATEDCOLUMN)	>>= sRelatedColumn;

				pNewData->SetSourceFieldName(sName);
				pNewData->SetDestFieldName(sRelatedColumn);
				m_vConnLineData.push_back(pNewData);
			}
		}
	} // if ( xColSup.is() )
	// NOTE : the caller is resposible for updating any other objects referencing the old LineDatas (for instance a ConnLine)

	////////////////////////////////////////////////////////////
	// Kardinalitaet bestimmen
	SetCardinality();

	return sal_True;
}
// -----------------------------------------------------------------------------

