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

//------------------------------------------------------
// testcomponent - Loads a service and its testcomponent from dlls performs a test.
// Expands the dll-names depending on the actual environment.
// Example : testcomponent stardiv.uno.io.Pipe stm
//
// Therefor the testcode must exist in teststm and the testservice must be named test.stardiv.uno.io.Pipe
//

#include <stdio.h>
#include <smart/com/sun/star/registry/XImplementationRegistration.hxx>
#include <smart/com/sun/star/lang/XComponent.hxx>
//#include <com/sun/star/registry/ stardiv/uno/repos/simplreg.hxx>

#include <vos/dynload.hxx>
#include <vos/diagnose.hxx>
#include <usr/services.hxx>
#include <vcl/svapp.hxx>
#include <usr/ustring.hxx>
#include <tools/string.hxx>
#include <vos/conditn.hxx>

#include <smart/com/sun/star/test/XSimpleTest.hxx>

using namespace rtl;
using namespace vos;
using namespace usr;


// Needed to switch on solaris threads
#ifdef SOLARIS
extern "C" void ChangeGlobalInit();
#endif

int __LOADONCALLAPI main (int argc, char **argv)
{

	if( argc < 3) {
		printf( "usage : testcomponent service dll [additional dlls]\n" );
		exit( 0 );
	}
#ifdef SOLARIS
	// switch on threads in solaris
	ChangeGlobalInit();
#endif

	// create service manager
//	XMultiServiceFactoryRef xSMgr = getProcessServiceManager();
	XMultiServiceFactoryRef xSMgr = createRegistryServiceManager();
	OSL_ASSERT( xSMgr.is() );
	registerUsrServices( xSMgr );
	setProcessServiceManager( xSMgr );

	XImplementationRegistrationRef xReg;
	XSimpleRegistryRef xSimpleReg;

	try	{
		// Create registration service
		XInterfaceRef x = xSMgr->createInstance(
			UString::createFromAscii( "com.sun.star.registry.ImplementationRegistration" ) );
		x->queryInterface( XImplementationRegistration::getSmartUik() , xReg );

/*		x = xSMgr->createInstance( L"stardiv.uno.repos.SimpleRegistry" );
		OSL_ASSERT( x.is() );
		x->queryInterface( XSimpleRegistry::getSmartUik() , xSimpleReg );
		OSL_ASSERT( xSimpleReg.is() );
	    xSimpleReg->open( L"testcomp.rdb" , FALSE , TRUE );
*/	}
	catch( Exception& e ) {
		printf( "%s\n" , OWStringToOString( e.getName() , CHARSET_SYSTEM ).getStr() );
		exit(1);
	}

	sal_Char szBuf[1024];
	OString sTestName;

	try {
		// Load dll for the tested component
		for( int n = 2 ; n <argc ; n ++ ) {
			ORealDynamicLoader::computeModuleName( argv[n] , szBuf, 1024 );
			UString aDllName( OStringToOWString( szBuf, CHARSET_SYSTEM ) );

			xReg->registerImplementation(
				UString::createFromAscii( "com.sun.star.loader.SharedLibrary" ),
				aDllName,
				xSimpleReg );
		}
	}
	catch( Exception& e ) {
		printf( "Couldn't reach dll %s\n" , szBuf );
		printf( "%s\n" , OWStringToOString( e.getName() , CHARSET_SYSTEM ).getStr() );

		exit(1);
	}


	try {
		// Load dll for the test component
		sTestName = "test";
		sTestName += argv[2];

		ORealDynamicLoader::computeModuleName( sTestName.getStr() , szBuf, 1024 );
		UString aDllName = OStringToOWString( szBuf, CHARSET_SYSTEM );
		xReg->registerImplementation(
			UString::createFromAscii( "com.sun.star.loader.SharedLibrary" ) ,
			aDllName,
			xSimpleReg );
	}
	catch( Exception& e ) {
		printf( "Couldn't reach dll %s\n" , szBuf );
		printf( "%s\n" , OWStringToOString( e.getName() , CHARSET_SYSTEM ).getStr() );
		exit(1);
	}


	// Instantiate test service
	sTestName = "test.";
	sTestName += argv[1];

	XInterfaceRef xIntTest = xSMgr->createInstance( OStringToOWString( sTestName , CHARSET_SYSTEM ) );
	XSimpleTestRef xTest( xIntTest , USR_QUERY );

	if( ! xTest.is() ) {
		printf( "Couldn't instantiate test service \n" );
		exit( 1 );
	}


	INT32 nHandle = 0;
	INT32 nNewHandle;
	INT32 nErrorCount = 0;
	INT32 nWarningCount = 0;

	// loop until all test are performed
	while( nHandle != -1 ) {

		// Instantiate serivce
		XInterfaceRef x = xSMgr->createInstance( OStringToOWString( argv[1] , CHARSET_SYSTEM ) );
		if( ! x.is() ) {
			printf( "Couldn't instantiate service !\n" );
			exit( 1 );	
		}

		// do the test
		try {		
			nNewHandle = xTest->test( OStringToOWString( argv[1] , CHARSET_SYSTEM ) , x , nHandle );
		}
		catch ( Exception& e ) {
			printf( "testcomponent : uncaught exception %s\n" , 
						OWStringToOString( e.getName(), CHARSET_SYSTEM ).getStr() );
			exit(1);
		}
		catch(...) {
			printf( "testcomponent : uncaught unknown exception\n"  );
			exit(1);
		}
		
		
		// print errors and warning
		Sequence<UString> seqErrors = xTest->getErrors();
		Sequence<UString> seqWarnings = xTest->getWarnings();
		if( seqWarnings.getLen() > nWarningCount ) {
			printf( "Warnings during test %d!\n" , nHandle );
			for( ; nWarningCount < seqWarnings.getLen() ; nWarningCount ++ ) {
				printf( "Warning\n%s\n---------\n" , 
					OWStringToOString( seqWarnings.getArray()[nWarningCount], CHARSET_SYSTEM ).getStr() );
			}			
		}


		if( seqErrors.getLen() > nErrorCount ) {
			printf( "Errors during test %d!\n" , nHandle );
			for( ; nErrorCount < seqErrors.getLen() ; nErrorCount ++ ) {
				printf( "%s\n" , 
							OWStringToOString( 
									seqErrors.getArray()[nErrorCount], CHARSET_SYSTEM ).getStr() );
			}
		}

		nHandle = nNewHandle;
	}

	if( xTest->testPassed() ) {
		printf( "Test passed !\n" );
	}
	else {
		printf( "Test failed !\n" );	
	}

	XComponentRef rComp( xSMgr , USR_QUERY );
	rComp->dispose();
	return 0;
}
