/**************************************************************
 * 
 * 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_cppuhelper.hxx"

// starting the executable:
// -env:UNO_CFG_URL=local;<absolute_path>..\\..\\test\\cfg_data;<absolute_path>\\cfg_update
// -env:UNO_TYPES=cpputest.rdb

#include <sal/main.h>

#include <stdio.h>

#include <rtl/strbuf.hxx>

#include <cppuhelper/implementationentry.hxx>
#include <cppuhelper/bootstrap.hxx>
#include <cppuhelper/implbase2.hxx>

#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XComponent.hpp>

#include <com/sun/star/registry/XImplementationRegistration.hpp>

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )


using namespace ::cppu;
using namespace ::rtl;
using namespace ::osl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

namespace cfg_test
{

//--------------------------------------------------------------------------------------------------
static Sequence< OUString > impl0_getSupportedServiceNames()
{
    OUString str( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bootstrap.TestComponent0") );
    return Sequence< OUString >( &str, 1 );
}
//--------------------------------------------------------------------------------------------------
static OUString impl0_getImplementationName()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.bootstrap.TestComponent0") );
}
//--------------------------------------------------------------------------------------------------
static Sequence< OUString > impl1_getSupportedServiceNames()
{
    OUString str( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bootstrap.TestComponent1") );
    return Sequence< OUString >( &str, 1 );
}
//--------------------------------------------------------------------------------------------------
static OUString impl1_getImplementationName()
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.bootstrap.TestComponent1") );
}

//==================================================================================================
class ServiceImpl0
    : public WeakImplHelper2< lang::XServiceInfo, lang::XInitialization >
{
	Reference< XComponentContext > m_xContext;
    
public:
    ServiceImpl0( Reference< XComponentContext > const & xContext ) SAL_THROW( () );

    // XInitialization
    virtual void SAL_CALL initialize( const Sequence< Any >& rArgs ) throw (Exception, RuntimeException);
    
	// XServiceInfo
	virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException);
	virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
	virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException);
};
//__________________________________________________________________________________________________
ServiceImpl0::ServiceImpl0( Reference< XComponentContext > const & xContext ) SAL_THROW( () )
    : m_xContext( xContext )
{
    sal_Int32 n;
    OUString val;
    
    // service properties
    OSL_VERIFY( m_xContext->getValueByName(
        OUSTR("/services/com.sun.star.bootstrap.TestComponent0/context-properties/serviceprop0") ) >>= n );
    OSL_VERIFY( n == 13 );
    OSL_VERIFY( m_xContext->getValueByName(
        OUSTR("/services/com.sun.star.bootstrap.TestComponent0/context-properties/serviceprop1") ) >>= val );
    OSL_VERIFY( val.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("value of serviceprop1") ) );
    // impl properties
    OSL_VERIFY( m_xContext->getValueByName(
        OUSTR("/implementations/com.sun.star.comp.bootstrap.TestComponent0/context-properties/implprop0") ) >>= n );
    OSL_VERIFY( n == 15 );
    OSL_VERIFY( m_xContext->getValueByName(
        OUSTR("/implementations/com.sun.star.comp.bootstrap.TestComponent0/context-properties/implprop1") ) >>= val );
    OSL_VERIFY( val.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("value of implprop1") ) );
}
// XInitialization
//__________________________________________________________________________________________________
void ServiceImpl0::initialize( const Sequence< Any >& rArgs )
    throw (Exception, RuntimeException)
{
    // check args
    OUString val;
    OSL_VERIFY( rArgs.getLength() == 3 );
    OSL_VERIFY( rArgs[ 0 ] >>= val );
    OSL_VERIFY( val.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("first argument") ) );
    OSL_VERIFY( rArgs[ 1 ] >>= val );
    OSL_VERIFY( val.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("second argument") ) );
    OSL_VERIFY( rArgs[ 2 ] >>= val );
    OSL_VERIFY( val.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("third argument") ) );
}
// XServiceInfo
//__________________________________________________________________________________________________
OUString ServiceImpl0::getImplementationName()
	throw(::com::sun::star::uno::RuntimeException)
{
	return impl0_getImplementationName();
}
//__________________________________________________________________________________________________
Sequence< OUString > ServiceImpl0::getSupportedServiceNames()
	throw(::com::sun::star::uno::RuntimeException)
{
	return impl0_getSupportedServiceNames();
}
//__________________________________________________________________________________________________
sal_Bool ServiceImpl0::supportsService( const OUString & rServiceName )
	throw(::com::sun::star::uno::RuntimeException)
{
	const Sequence< OUString > & rSNL = getSupportedServiceNames();
	const OUString * pArray = rSNL.getConstArray();
	for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
	{
		if (pArray[nPos] == rServiceName)
			return sal_True;
	}
	return sal_False;
}

//==================================================================================================
class ServiceImpl1 : public ServiceImpl0
{
public:
    inline ServiceImpl1( Reference< XComponentContext > const & xContext ) SAL_THROW( () )
        : ServiceImpl0( xContext )
        {}
    
    // XServiceInfo
	virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException);
	virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
};
//__________________________________________________________________________________________________
OUString ServiceImpl1::getImplementationName()
	throw(::com::sun::star::uno::RuntimeException)
{
	return impl1_getImplementationName();
}
//__________________________________________________________________________________________________
Sequence< OUString > ServiceImpl1::getSupportedServiceNames()
	throw(::com::sun::star::uno::RuntimeException)
{
	return impl1_getSupportedServiceNames();
}

//==================================================================================================
static Reference< XInterface > SAL_CALL ServiceImpl0_create(
    Reference< XComponentContext > const & xContext )
	SAL_THROW( (Exception) )
{
	return (OWeakObject *)new ServiceImpl0( xContext );
}
//==================================================================================================
static Reference< XInterface > SAL_CALL ServiceImpl1_create(
    Reference< XComponentContext > const & xContext )
	SAL_THROW( (Exception) )
{
	return (OWeakObject *)new ServiceImpl1( xContext );
}

} // namespace cfg_test

static struct ImplementationEntry g_entries[] =
{
	{
		::cfg_test::ServiceImpl0_create, ::cfg_test::impl0_getImplementationName,
		::cfg_test::impl0_getSupportedServiceNames, createSingleComponentFactory,
		0, 0
	},
	{
		::cfg_test::ServiceImpl1_create, ::cfg_test::impl1_getImplementationName,
		::cfg_test::impl1_getSupportedServiceNames, createSingleComponentFactory,
		0, 0
	},
	{ 0, 0, 0, 0, 0, 0 }
};

// component exports
extern "C"
{
//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
	const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
{
	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
sal_Bool SAL_CALL component_writeInfo(
	void * pServiceManager, void * pRegistryKey )
{
	return component_writeInfoHelper(
        pServiceManager, pRegistryKey, g_entries );
}
//==================================================================================================
void * SAL_CALL component_getFactory(
	const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
	return component_getFactoryHelper(
        pImplName, pServiceManager, pRegistryKey , g_entries );
}
}


//##################################################################################################
//##################################################################################################
//##################################################################################################

SAL_IMPLEMENT_MAIN()
{
    try
    {
        Reference< XComponentContext > xContext( defaultBootstrap_InitialComponentContext() );
        Reference< lang::XMultiComponentFactory > xMgr( xContext->getServiceManager() );
        
        // show what is in context
        xContext->getValueByName( OUSTR("dump_maps") );
        
        sal_Int32 n;
        OSL_VERIFY( xContext->getValueByName( OUSTR("/global-context-properties/TestValue") ) >>= n );
        ::fprintf( stderr, "> n=%d\n", n );
        
        Reference< XInterface > x;
        OSL_VERIFY( !(xContext->getValueByName( OUSTR("/singletons/my_converter") ) >>= x) );
        OSL_VERIFY( xContext->getValueByName( OUSTR("/singletons/com.sun.star.script.theConverter") ) >>= x );
        OSL_VERIFY( xContext->getValueByName( OUSTR("/singletons/com.sun.star.bootstrap.theTestComponent0") ) >>= x );
        
        ::fprintf( stderr, "> registering service...\n", n );
#if defined(SAL_W32) || defined(SAL_OS2)
        OUString libName( OUSTR("cfg_test.dll") );
#elif defined(SAL_UNX)
        OUString libName( OUSTR("libcfg_test.so") );
#endif
		Reference< registry::XImplementationRegistration > xImplReg( xMgr->createInstanceWithContext(
            OUSTR("com.sun.star.registry.ImplementationRegistration"), xContext ), UNO_QUERY );
		OSL_ENSURE( xImplReg.is(), "### no impl reg!" );
		xImplReg->registerImplementation(
            OUSTR("com.sun.star.loader.SharedLibrary"), libName,
            Reference< registry::XSimpleRegistry >() );
		
        OSL_VERIFY( (x = xMgr->createInstanceWithContext( OUSTR("com.sun.star.bootstrap.TestComponent0"), xContext )).is() );
        OSL_VERIFY( (x = xMgr->createInstanceWithContext( OUSTR("com.sun.star.bootstrap.TestComponent1"), xContext )).is() );
        
        Reference< lang::XComponent > xComp( xContext, UNO_QUERY );
        if (xComp.is())
        {
            xComp->dispose();
        }
        return 0;
    }
    catch (Exception & exc)
    {
        OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
        ::fprintf( stderr, "# caught exception: %s\n", str.getStr() );
        return 1;
    }
}
