/**************************************************************
 * 
 * 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 <stdio.h>
#include "connectivity/CommonTools.hxx"
#include "connectivity/dbtools.hxx"
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/Time.hpp>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <comphelper/extract.hxx>
#include <cppuhelper/interfacecontainer.h>
#include "TConnection.hxx"
#include <comphelper/types.hxx>
#include <com/sun/star/java/XJavaVM.hpp>
#include <rtl/process.h>

using namespace ::comphelper;
inline sal_Unicode rtl_ascii_toUpperCase( sal_Unicode ch )
{
    return ch >= 0x0061 && ch <= 0x007a ? ch + 0x20 : ch;
}

namespace connectivity
{
	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::beans;
	using namespace dbtools;
	namespace starjava	= com::sun::star::java;
	//------------------------------------------------------------------------------
	const sal_Unicode CHAR_PLACE = '_';
	const sal_Unicode CHAR_WILD  = '%';
	// -------------------------------------------------------------------------
	sal_Bool match(const sal_Unicode* pWild, const sal_Unicode* pStr, const sal_Unicode cEscape)
	{
		int    pos=0;
		int    flag=0;

		while ( *pWild || flag )
		{
			switch (*pWild)
			{
				case CHAR_PLACE:
					if ( *pStr == 0 )
						return sal_False;
					break;
				default:
					if (*pWild && (*pWild == cEscape) && ((*(pWild+1)== CHAR_PLACE) || (*(pWild+1) == CHAR_WILD)) )
						pWild++;
					if ( rtl_ascii_toUpperCase(*pWild) != rtl_ascii_toUpperCase(*pStr) )
						if ( !pos )
							return sal_False;
						else
							pWild += pos;
					else
						break;          // ACHTUNG laeuft unter bestimmten
										// Umstaenden in den nachsten case rein!!
				case CHAR_WILD:
					while ( *pWild == CHAR_WILD )
						pWild++;
					if ( *pWild == 0 )
						return sal_True;
					flag = 1;
					pos  = 0;
					if ( *pStr == 0 )
						return ( *pWild == 0 );
					while ( *pStr && *pStr != *pWild )
					{
						if ( *pWild == CHAR_PLACE ) {
							pWild++;
							while ( *pWild == CHAR_WILD )
								pWild++;
						}
						pStr++;
						if ( *pStr == 0 )
							return ( *pWild == 0 );
					}
					break;
			}
			if ( *pWild != 0 )
				pWild++;
			if ( *pStr != 0 )
				pStr++;
			else
				flag = 0;
			if ( flag )
				pos--;
		}
		return ( *pStr == 0 ) && ( *pWild == 0 );
	}
	//------------------------------------------------------------------
	rtl::OUString toDateString(const ::com::sun::star::util::Date& rDate)
	{
		sal_Char s[11];
		snprintf(s,
				sizeof(s),
				"%04d-%02d-%02d",
				(int)rDate.Year,
				(int)rDate.Month,
				(int)rDate.Day);
		s[10] = 0;
		return rtl::OUString::createFromAscii(s);
	}

	//------------------------------------------------------------------
	rtl::OUString toTimeString(const ::com::sun::star::util::Time& rTime)
	{
		sal_Char s[9];
		snprintf(s,
				sizeof(s),
				"%02d:%02d:%02d",
				(int)rTime.Hours,
				(int)rTime.Minutes,
				(int)rTime.Seconds);
		s[8] = 0;
		return rtl::OUString::createFromAscii(s);
	}

	//------------------------------------------------------------------
	rtl::OUString toDateTimeString(const ::com::sun::star::util::DateTime& rDateTime)
	{
		sal_Char s[21];
		snprintf(s,
				sizeof(s),
				"%04d-%02d-%02d %02d:%02d:%02d",
				(int)rDateTime.Year,
				(int)rDateTime.Month,
				(int)rDateTime.Day,
				(int)rDateTime.Hours,
				(int)rDateTime.Minutes,
				(int)rDateTime.Seconds);
		s[20] = 0;
		return rtl::OUString::createFromAscii(s);
	}


	//--------------------------------------------------------------------------------------------------
	rtl::OUString toString(const Any& rValue)
	{
		rtl::OUString aRes;
		TypeClass aDestinationClass = rValue.getValueType().getTypeClass();

		switch (aDestinationClass)
		{
			case TypeClass_CHAR:
				aRes = ::rtl::OUString::valueOf(*(sal_Unicode*)rValue.getValue());
				break;
			case TypeClass_FLOAT:
				aRes = ::rtl::OUString::valueOf(*(float*)rValue.getValue());
				break;
			case TypeClass_DOUBLE:
				aRes = ::rtl::OUString::valueOf(*(double*)rValue.getValue());
				break;
			case TypeClass_BOOLEAN:
				aRes = ::rtl::OUString::valueOf((sal_Int32)*(sal_Bool*)rValue.getValue());
				break;
			case TypeClass_BYTE:
			case TypeClass_SHORT:
			case TypeClass_LONG:
				aRes = ::rtl::OUString::valueOf(*(sal_Int32*)rValue.getValue());
				break;
            case TypeClass_HYPER:
		    {
			    sal_Int64 nValue = 0;
			    OSL_VERIFY( rValue >>= nValue );
                aRes = ::rtl::OUString::valueOf(nValue);
		    }
			case TypeClass_STRING:
				rValue >>= aRes;
				break;
			case TypeClass_STRUCT:
				if (rValue.getValueType() == ::getCppuType((const ::com::sun::star::util::Date*)0))
				{
					::com::sun::star::util::Date aDate;
					rValue >>= aDate;
					aRes = toDateString(aDate);
				}
				else if (rValue.getValueType() == ::getCppuType((const ::com::sun::star::util::DateTime*)0))
				{
					::com::sun::star::util::DateTime aDT;
					rValue >>= aDT;
					aRes = toDateTimeString(aDT);
				}
				else if (rValue.getValueType() == ::getCppuType((const ::com::sun::star::util::Time*)0))
				{
					::com::sun::star::util::Time aTime;
					rValue >>= aTime;
					aRes = toTimeString(aTime);
				}

				break;
			default:
				;
		}
		return aRes;
	}

	// -----------------------------------------------------------------------------
	::rtl::Reference< jvmaccess::VirtualMachine > getJavaVM(const Reference<XMultiServiceFactory >& _rxFactory)
	{
		::rtl::Reference< jvmaccess::VirtualMachine > aRet;
		OSL_ENSURE(_rxFactory.is(),"No XMultiServiceFactory a.v.!");
		if(!_rxFactory.is())
			return aRet;

		try
		{
			Reference< starjava::XJavaVM > xVM(_rxFactory->createInstance(
				rtl::OUString::createFromAscii("com.sun.star.java.JavaVirtualMachine")), UNO_QUERY);

			OSL_ENSURE(_rxFactory.is(),"InitJava: I have no factory!");
			if (!xVM.is() || !_rxFactory.is())
				throw Exception(); // -2;

			Sequence<sal_Int8> processID(16);
			rtl_getGlobalProcessId( (sal_uInt8*) processID.getArray() );
			processID.realloc(17);
			processID[16] = 0;

			Any uaJVM = xVM->getJavaVM( processID );

			if (!uaJVM.hasValue())
				throw Exception(); // -5
			else
			{
				sal_Int32 nValue = 0;
				jvmaccess::VirtualMachine* pJVM = NULL;
				if ( uaJVM >>= nValue )
					pJVM = reinterpret_cast< jvmaccess::VirtualMachine* > (nValue);
				else
				{
					sal_Int64 nTemp = 0;
					uaJVM >>= nTemp;
					pJVM = reinterpret_cast< jvmaccess::VirtualMachine* > (nTemp);
				}
				aRet = pJVM;
			}
		}
		catch (Exception&)
		{
		}

		return aRet;
	}
	//------------------------------------------------------------------------------
	sal_Bool existsJavaClassByName( const ::rtl::Reference< jvmaccess::VirtualMachine >& _pJVM,const ::rtl::OUString& _sClassName )
	{
		sal_Bool bRet = sal_False;
#ifdef SOLAR_JAVA
		if ( _pJVM.is() )
		{
			jvmaccess::VirtualMachine::AttachGuard aGuard(_pJVM);
			JNIEnv*	pEnv = aGuard.getEnvironment();
			if( pEnv )
			{
				::rtl::OString sClassName = ::rtl::OUStringToOString(_sClassName, RTL_TEXTENCODING_ASCII_US);
				sClassName = sClassName.replace('.','/');
				jobject out = pEnv->FindClass(sClassName);
				bRet = out != NULL;
				pEnv->DeleteLocalRef( out );
			}
		}
#endif
		return bRet;
	}

}

#include <ctype.h>		//isdigit
namespace dbtools
{
//------------------------------------------------------------------
sal_Bool isCharOk(sal_Unicode c,const ::rtl::OUString& _rSpecials)
{

    return ( ((c >= 97) && (c <= 122)) || ((c >= 65) && (c <=  90)) || ((c >= 48) && (c <=  57)) ||
          c == '_' || _rSpecials.indexOf(c) != -1);
}

//------------------------------------------------------------------------------
sal_Bool isValidSQLName(const ::rtl::OUString& rName,const ::rtl::OUString& _rSpecials)
{
    // Ueberpruefung auf korrekte Namensgebung im SQL Sinne
    // Dieses ist wichtig fuer Tabellennamen beispielsweise
	const sal_Unicode* pStr = rName.getStr();
	if (*pStr > 127 || isdigit(*pStr))
		return sal_False;

	for (; *pStr; ++pStr )
		if(!isCharOk(*pStr,_rSpecials))
			return sal_False;

	if	(	rName.getLength()
		&&	(	(rName.toChar() == '_')
			||	(	(rName.toChar() >= '0')
				&&	(rName.toChar() <= '9')
				)
			)
		)
		return sal_False;
	// the SQL-Standard requires the first character to be an alphabetic character, which
	// isn't easy to decide in UniCode ...
	// So we just prohibit the characters which already lead to problems ....
	// 11.04.00 - 74902 - FS

	return sal_True;
}
//------------------------------------------------------------------
// Erzeugt einen neuen Namen falls noetig
::rtl::OUString convertName2SQLName(const ::rtl::OUString& rName,const ::rtl::OUString& _rSpecials)
{
	if(isValidSQLName(rName,_rSpecials))
		return rName;
	::rtl::OUString aNewName(rName);
	const sal_Unicode* pStr = rName.getStr();
	sal_Int32 nLength = rName.getLength();
	sal_Bool bValid(*pStr < 128 && !isdigit(*pStr));
	for (sal_Int32 i=0; bValid && i < nLength; ++pStr,++i )
		if(!isCharOk(*pStr,_rSpecials))
		{
			aNewName = aNewName.replace(*pStr,'_');
			pStr = aNewName.getStr() + i;
		}

	if ( !bValid )
		aNewName = ::rtl::OUString();

	return aNewName;
}
//------------------------------------------------------------------------------
::rtl::OUString quoteName(const ::rtl::OUString& _rQuote, const ::rtl::OUString& _rName)
{
	::rtl::OUString sName = _rName;
	if(_rQuote.getLength() && _rQuote.toChar() != ' ')
		sName = _rQuote + _rName + _rQuote;
	return sName;
}


}
