/**************************************************************
 *
 * 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 depending 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 orientation 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 responsible for updating any other objects referencing the old LineDatas (for instance a ConnLine)

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

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