/**************************************************************
 * 
 * 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 "KStatement.hxx"
#include "KConnection.hxx"
#include "KDriver.hxx"
#include "KResultSet.hxx"
#include "KResultSetMetaData.hxx"
#include "kcondition.hxx"
#include "korder.hxx"
#include "TConnection.hxx"
#include <connectivity/dbexception.hxx>
#include "resource/kab_res.hrc"
#include "resource/sharedresources.hxx"


#if OSL_DEBUG_LEVEL > 0
# define OUtoCStr( x ) ( ::rtl::OUStringToOString ( (x), RTL_TEXTENCODING_ASCII_US).getStr())
#else /* OSL_DEBUG_LEVEL */
# define OUtoCStr( x ) ("dummy")
#endif /* OSL_DEBUG_LEVEL */

using namespace connectivity::kab;
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::sdbcx;
using namespace com::sun::star::container;
using namespace com::sun::star::io;
using namespace com::sun::star::util;

namespace
{
    void lcl_throwError(sal_uInt16 _nErrorId)
    {
        ::connectivity::SharedResources aResources;
        const ::rtl::OUString sError( aResources.getResourceString(_nErrorId) );
        ::dbtools::throwGenericSQLException(sError,NULL);
    }
}

IMPLEMENT_SERVICE_INFO(KabStatement, "com.sun.star.sdbc.drivers.KabStatement", "com.sun.star.sdbc.Statement");
//------------------------------------------------------------------------------
KabCommonStatement::KabCommonStatement(KabConnection* _pConnection ) 
	: KabCommonStatement_BASE(m_aMutex),
	OPropertySetHelper(KabCommonStatement_BASE::rBHelper),
    m_aParser(_pConnection->getDriver()->getMSFactory()),
    m_aSQLIterator(_pConnection, _pConnection->createCatalog()->getTables(), m_aParser, NULL ),
	m_pParseTree(NULL),
	m_pConnection(_pConnection),
    rBHelper(KabCommonStatement_BASE::rBHelper)
{
	m_pConnection->acquire();
}
// -----------------------------------------------------------------------------
KabCommonStatement::~KabCommonStatement()
{
}
// -----------------------------------------------------------------------------
void KabCommonStatement::disposing()
{
	KabCommonStatement_BASE::disposing();
}
// -----------------------------------------------------------------------------
void KabCommonStatement::resetParameters() const throw(::com::sun::star::sdbc::SQLException)
{
    lcl_throwError(STR_PARA_ONLY_PREPARED);
}
// -----------------------------------------------------------------------------
void KabCommonStatement::getNextParameter(::rtl::OUString &) const throw(::com::sun::star::sdbc::SQLException)
{
	lcl_throwError(STR_PARA_ONLY_PREPARED);
}
// -----------------------------------------------------------------------------
KabCondition *KabCommonStatement::analyseWhereClause(const OSQLParseNode *pParseNode) const throw(SQLException)
{
	if (pParseNode->count() == 3)
	{
		const OSQLParseNode *pLeft = pParseNode->getChild(0),
		                    *pMiddle = pParseNode->getChild(1),
		                    *pRight = pParseNode->getChild(2);

		// WHERE ( ... ) ?
		if (SQL_ISPUNCTUATION(pLeft, "(") && SQL_ISPUNCTUATION(pRight, ")"))
		{
		  	return analyseWhereClause(pMiddle);
		}
		else if (SQL_ISRULE(pParseNode, comparison_predicate))
		{
			if (pLeft->isToken() && pRight->isToken())
			{
				switch (pMiddle->getNodeType())
				{
					case SQL_NODE_EQUAL:
						// WHERE 0 = 1
						return new KabConditionConstant(pLeft->getTokenValue() == pRight->getTokenValue());

					case SQL_NODE_NOTEQUAL:
						// WHERE 0 <> 1
						// (might not be correct SQL... don't care, handling anyway)
						return new KabConditionConstant(pLeft->getTokenValue() != pRight->getTokenValue());

					default:
                        break;
				}
			}
			else if (SQL_ISRULE(pLeft, column_ref))
			{
				::rtl::OUString sColumnName,
				                sTableRange;

				m_aSQLIterator.getColumnRange(pLeft, sColumnName, sTableRange);

				if (pRight->isToken() || SQL_ISRULE(pRight, parameter))
				{
					::rtl::OUString sMatchString;

					if (pRight->isToken())						// WHERE Name = 'Doe'
						sMatchString = pRight->getTokenValue();
					else if (SQL_ISRULE(pRight, parameter))		// WHERE Name = ?
						getNextParameter(sMatchString);

					switch (pMiddle->getNodeType())
					{
						case SQL_NODE_EQUAL:
							// WHERE Name = 'Smith'
							return new KabConditionEqual(sColumnName, sMatchString);

			 			case SQL_NODE_NOTEQUAL:
							// WHERE Name <> 'Jones'
							return new KabConditionDifferent(sColumnName, sMatchString);

						default:
							break;
					}
				}
			}
		}
		else if (SQL_ISRULE(pParseNode, search_condition))
		{
			if (SQL_ISTOKEN(pMiddle, OR))
			{
				// WHERE Name = 'Smith' OR Name = 'Jones'
				return new KabConditionOr(
					analyseWhereClause(pLeft),
					analyseWhereClause(pRight));
			}
		}
		else if (SQL_ISRULE(pParseNode, boolean_term))
		{
			if (SQL_ISTOKEN(pMiddle, AND))
			{
				// WHERE Name = 'Smith' AND "Given Name" = 'Peter'
				return new KabConditionAnd(
					analyseWhereClause(pLeft),
					analyseWhereClause(pRight));
			}
		}
	}
	else if (SQL_ISRULE(pParseNode, test_for_null) || SQL_ISRULE(pParseNode, like_predicate))
	{
        const OSQLParseNode *pLeft = pParseNode->getChild(0);
        const OSQLParseNode* pPart2 = pParseNode->getChild(1);		
        const OSQLParseNode *pMiddleLeft = pPart2->getChild(0),
	                        *pMiddleRight = pPart2->getChild(1),
	                        *pRight = pPart2->getChild(2);		                    

		if (SQL_ISRULE(pParseNode, test_for_null))
		{
			if (SQL_ISRULE(pLeft, column_ref) &&
                            SQL_ISTOKEN(pMiddleLeft, IS) &&
                            SQL_ISTOKEN(pRight, NULL))
			{
				::rtl::OUString sColumnName,
				                sTableRange;

				m_aSQLIterator.getColumnRange(pLeft, sColumnName, sTableRange);

				if (SQL_ISTOKEN(pMiddleRight, NOT))
				{
					// WHERE "Mobile Phone" IS NOT NULL
					return new KabConditionNotNull(sColumnName);
				}
				else
				{
					// WHERE "Mobile Phone" IS NULL
					return new KabConditionNull(sColumnName);
				}
			}
		}
		else if (SQL_ISRULE(pParseNode, like_predicate))
		{
			if (SQL_ISRULE(pLeft, column_ref))
			{
				::rtl::OUString sColumnName,
				                sTableRange;

				m_aSQLIterator.getColumnRange(pLeft, sColumnName, sTableRange);

				if (pMiddleRight->isToken() || SQL_ISRULE(pMiddleRight, parameter))
				{
					::rtl::OUString sMatchString;

					if (pMiddleRight->isToken())					// WHERE Name LIKE 'Sm%'
						sMatchString = pMiddleRight->getTokenValue();
					else if (SQL_ISRULE(pMiddleRight, parameter))	// WHERE Name LIKE ?
						getNextParameter(sMatchString);

					return new KabConditionSimilar(sColumnName, sMatchString);
				}
			}
		}
	}

    lcl_throwError(STR_QUERY_TOO_COMPLEX);

    // Unreachable:
    OSL_ASSERT(false);
    return 0;
}
// -----------------------------------------------------------------------------
KabOrder *KabCommonStatement::analyseOrderByClause(const OSQLParseNode *pParseNode) const throw(SQLException)
{
	if (SQL_ISRULE(pParseNode, ordering_spec_commalist))
	{
		KabComplexOrder *list = new KabComplexOrder();
		sal_uInt32 n = pParseNode->count();

		// Iterate through the ordering columns
		for (sal_uInt32 i = 0; i < n; i++)
		{
			list->addOrder
				(analyseOrderByClause(pParseNode->getChild(i)));
		}

		return list;
	}
	else if (SQL_ISRULE(pParseNode, ordering_spec))
	{
		if (pParseNode->count() == 2)
		{
			OSQLParseNode* pColumnRef = pParseNode->getChild(0);
			OSQLParseNode* pAscendingDescending = pParseNode->getChild(1);

			if (SQL_ISRULE(pColumnRef, column_ref))
			{
				if (pColumnRef->count() == 3)
					pColumnRef = pColumnRef->getChild(2);

				if (pColumnRef->count() == 1)
				{
					::rtl::OUString sColumnName =
						pColumnRef->getChild(0)->getTokenValue();
					sal_Bool bAscending =
						SQL_ISTOKEN(pAscendingDescending, DESC)?
						sal_False:
						sal_True;

					return new KabSimpleOrder(sColumnName, bAscending);
				}
			}
		}
	}
    lcl_throwError(STR_QUERY_TOO_COMPLEX);
    // Unreachable:
    OSL_ASSERT(false);
    return 0;
}
//------------------------------------------------------------------------------
sal_Bool KabCommonStatement::isTableKnown(KabResultSet *pResult) const
{
	// can handle requests like        SELECT * FROM addresses addresses
	// but cannot handle requests like SELECT * FROM addresses persons
	if (m_aSQLIterator.getTables().size() != 1)
		return sal_False;

	if (m_aSQLIterator.getTables().begin()->first != pResult->getMetaData()->getTableName(0))
		return sal_False;

	return sal_True;
}
//------------------------------------------------------------------------------
void KabCommonStatement::setKabFields(KabResultSet *pResult) const throw(SQLException)
{
	::vos::ORef<connectivity::OSQLColumns> xColumns;	// selected columns
	KabResultSetMetaData *pMeta;				// meta information - holds the list of KAddressBook fields

	xColumns = m_aSQLIterator.getSelectColumns();
	if (!xColumns.isValid())
	{
        lcl_throwError(STR_INVALID_COLUMN_SELECTION);
	}
	pMeta = static_cast<KabResultSetMetaData *>(pResult->getMetaData().get());
	pMeta->setKabFields(xColumns);
}
// -------------------------------------------------------------------------
void KabCommonStatement::selectAddressees(KabResultSet *pResult) const throw(SQLException)
{
	const OSQLParseNode *pParseNode;
	KabCondition *pCondition;

	pParseNode = m_aSQLIterator.getWhereTree();
	if (pParseNode != NULL)
	{
		if (SQL_ISRULE(pParseNode, where_clause))
		{
			resetParameters();
			pParseNode = pParseNode->getChild(1);
			pCondition = analyseWhereClause(pParseNode);
			if (pCondition->isAlwaysTrue())
				pResult->allKabAddressees();
			else if (!pCondition->isAlwaysFalse())
				pResult->someKabAddressees(pCondition);
			delete pCondition;
			return;
		}
	}

	// no WHERE clause: get all rows
	pResult->allKabAddressees();
}
// -------------------------------------------------------------------------
void KabCommonStatement::sortAddressees(KabResultSet *pResult) const throw(SQLException)
{
	const OSQLParseNode *pParseNode;
	KabOrder *pOrder;

	pParseNode = m_aSQLIterator.getOrderTree();
	if (pParseNode != NULL)
	{
		if (SQL_ISRULE(pParseNode, opt_order_by_clause))
		{
			pParseNode = pParseNode->getChild(2);
			pOrder = analyseOrderByClause(pParseNode);
			pResult->sortKabAddressees(pOrder);
			delete pOrder;
		}
	}
}
//-----------------------------------------------------------------------------
Any SAL_CALL KabCommonStatement::queryInterface( const Type & rType ) throw(RuntimeException)
{
	Any aRet = KabCommonStatement_BASE::queryInterface(rType);
	if (!aRet.hasValue())
		aRet = OPropertySetHelper::queryInterface(rType);
	return aRet;
}
// -------------------------------------------------------------------------
Sequence< Type > SAL_CALL KabCommonStatement::getTypes(  ) throw(RuntimeException)
{
	::cppu::OTypeCollection aTypes(	::getCppuType( (const Reference< XMultiPropertySet > *)0 ),
									::getCppuType( (const Reference< XFastPropertySet > *)0 ),
									::getCppuType( (const Reference< XPropertySet > *)0 ));

	return comphelper::concatSequences(aTypes.getTypes(),KabCommonStatement_BASE::getTypes());
}
// -------------------------------------------------------------------------
void SAL_CALL KabCommonStatement::cancel(  ) throw(RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	checkDisposed(KabCommonStatement_BASE::rBHelper.bDisposed);
	// cancel the current sql statement
}
// -------------------------------------------------------------------------
void SAL_CALL KabCommonStatement::close(  ) throw(SQLException, RuntimeException)
{
	{
		::osl::MutexGuard aGuard( m_aMutex );
		checkDisposed(KabCommonStatement_BASE::rBHelper.bDisposed);
			
	}
	dispose();
}
// -------------------------------------------------------------------------
sal_Bool SAL_CALL KabCommonStatement::execute(
		const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(KabCommonStatement_BASE::rBHelper.bDisposed);

	Reference< XResultSet > xRS = executeQuery(sql);

	return xRS.is();
}
// -------------------------------------------------------------------------
Reference< XResultSet > SAL_CALL KabCommonStatement::executeQuery(
		const ::rtl::OUString& sql ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(KabCommonStatement_BASE::rBHelper.bDisposed);

OSL_TRACE("KDE Address book - SQL Request: %s", OUtoCStr(sql));

	KabResultSet* pResult = new KabResultSet(this);
	Reference< XResultSet > xRS = pResult;
	::rtl::OUString aErr;

	m_pParseTree = m_aParser.parseTree(aErr, sql);
	if (m_pParseTree == NULL)
		throw SQLException(aErr, *this, aErr, 0, Any());

	m_aSQLIterator.setParseTree(m_pParseTree);
	m_aSQLIterator.traverseAll();
	switch (m_aSQLIterator.getStatementType())
	{
		case SQL_STATEMENT_SELECT:
			if (isTableKnown(pResult))		// FROM which table ?
			{
				setKabFields(pResult);		// SELECT which columns ?
				selectAddressees(pResult);	// WHERE which condition ?
				sortAddressees(pResult);	// ORDER BY which columns ?
// To be continued: DISTINCT
//				    etc...
			}
			break;

		default:
// To be continued: UPDATE
//				    DELETE
//				    etc...
            lcl_throwError(STR_QUERY_TOO_COMPLEX);
	}

	return xRS;
}
// -------------------------------------------------------------------------
Reference< XConnection > SAL_CALL KabCommonStatement::getConnection(  ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(KabCommonStatement_BASE::rBHelper.bDisposed);
		
	// just return our connection here
	return (Reference< XConnection >) m_pConnection;
}
// -------------------------------------------------------------------------
sal_Int32 SAL_CALL KabCommonStatement::executeUpdate( const ::rtl::OUString& ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(KabCommonStatement_BASE::rBHelper.bDisposed);
		
	// the return values gives information about how many rows are affected by executing the sql statement		
	return 0;
}
// -------------------------------------------------------------------------
Any SAL_CALL KabCommonStatement::getWarnings(  ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(KabCommonStatement_BASE::rBHelper.bDisposed);

	return makeAny(m_aLastWarning);
}
// -------------------------------------------------------------------------
void SAL_CALL KabCommonStatement::clearWarnings(  ) throw(SQLException, RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	checkDisposed(KabCommonStatement_BASE::rBHelper.bDisposed);

	m_aLastWarning = SQLWarning();
}
// -------------------------------------------------------------------------
::cppu::IPropertyArrayHelper* KabCommonStatement::createArrayHelper( ) const
{
	// this properties are defined by the service statement
	// they must be in alphabetic order
	Sequence< Property > aProps(10);
	Property* pProperties = aProps.getArray();
	sal_Int32 nPos = 0;
	DECL_PROP0(CURSORNAME,	::rtl::OUString);
	DECL_BOOL_PROP0(ESCAPEPROCESSING);
	DECL_PROP0(FETCHDIRECTION,sal_Int32);
	DECL_PROP0(FETCHSIZE,	sal_Int32);
	DECL_PROP0(MAXFIELDSIZE,sal_Int32);
	DECL_PROP0(MAXROWS,		sal_Int32);
	DECL_PROP0(QUERYTIMEOUT,sal_Int32);
	DECL_PROP0(RESULTSETCONCURRENCY,sal_Int32);
	DECL_PROP0(RESULTSETTYPE,sal_Int32);
	DECL_BOOL_PROP0(USEBOOKMARKS);

	return new ::cppu::OPropertyArrayHelper(aProps);
}
// -------------------------------------------------------------------------
::cppu::IPropertyArrayHelper & KabCommonStatement::getInfoHelper()
{
	return *const_cast<KabCommonStatement*>(this)->getArrayHelper();
}
// -------------------------------------------------------------------------
sal_Bool KabCommonStatement::convertFastPropertyValue(
		Any &,
		Any &,
		sal_Int32,
		const Any&) throw (::com::sun::star::lang::IllegalArgumentException)
{
	sal_Bool bConverted = sal_False;
	// here we have to try to convert 
	return bConverted;
}
// -------------------------------------------------------------------------
void KabCommonStatement::setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any&) throw (Exception)
{
	// set the value to whatever is necessary
	switch (nHandle)
	{
		case PROPERTY_ID_QUERYTIMEOUT:
		case PROPERTY_ID_MAXFIELDSIZE:
		case PROPERTY_ID_MAXROWS:
		case PROPERTY_ID_CURSORNAME:
		case PROPERTY_ID_RESULTSETCONCURRENCY:
		case PROPERTY_ID_RESULTSETTYPE:
		case PROPERTY_ID_FETCHDIRECTION:
		case PROPERTY_ID_FETCHSIZE:
		case PROPERTY_ID_ESCAPEPROCESSING:
		case PROPERTY_ID_USEBOOKMARKS:
		default:
			;
	}
}
// -------------------------------------------------------------------------
void KabCommonStatement::getFastPropertyValue(Any&,sal_Int32 nHandle) const
{
	switch (nHandle)
	{
		case PROPERTY_ID_QUERYTIMEOUT:
		case PROPERTY_ID_MAXFIELDSIZE:
		case PROPERTY_ID_MAXROWS:
		case PROPERTY_ID_CURSORNAME:
		case PROPERTY_ID_RESULTSETCONCURRENCY:
		case PROPERTY_ID_RESULTSETTYPE:
		case PROPERTY_ID_FETCHDIRECTION:
		case PROPERTY_ID_FETCHSIZE:
		case PROPERTY_ID_ESCAPEPROCESSING:
		case PROPERTY_ID_USEBOOKMARKS:
		default:
			;
	}
}
// -----------------------------------------------------------------------------
void SAL_CALL KabCommonStatement::acquire() throw()
{
	KabCommonStatement_BASE::acquire();
}
// -----------------------------------------------------------------------------
void SAL_CALL KabCommonStatement::release() throw()
{
	KabCommonStatement_BASE::release();
}
// -----------------------------------------------------------------------------
Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL KabCommonStatement::getPropertySetInfo(  ) throw(RuntimeException)
{
	return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
}
// -----------------------------------------------------------------------------
KabStatement::KabStatement(KabConnection* _pConnection)
	: KabStatement_BASE(_pConnection)
{
}
