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


#include <cstdarg>
#include <osl/diagnose.h>
#include <osl/process.h>

#include <rtl/process.h>
#include <rtl/ustrbuf.hxx>

#include <uno/environment.h>
#include <uno/mapping.hxx>
#include "com/sun/star/uno/RuntimeException.hpp"

#include <cppuhelper/servicefactory.hxx>

#ifdef LINUX
#undef minor
#undef major
#endif

#include <com/sun/star/java/XJavaVM.hpp>

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

#include "jni.h"

#include <cppuhelper/factory.hxx>
#include <cppuhelper/implementationentry.hxx>

#include <cppuhelper/implbase2.hxx>

#include <com/sun/star/loader/XImplementationLoader.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>

#include "jvmaccess/unovirtualmachine.hxx"
#include "jvmaccess/virtualmachine.hxx"

namespace css = com::sun::star;

using namespace ::com::sun::star::java;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::loader;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::registry;

using namespace ::cppu;
using namespace ::rtl;
using namespace ::osl;

namespace stoc_javaloader {

static Mutex & getInitMutex();

static Sequence< OUString > loader_getSupportedServiceNames()
{
    static Sequence < OUString > *pNames = 0;
    if( ! pNames )
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if( !pNames )
        {
            static Sequence< OUString > seqNames(2);
            seqNames.getArray()[0] = OUString(
                RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Java") );
            seqNames.getArray()[1] = OUString(
                RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Java2") );
            pNames = &seqNames;
        }
    }
    return *pNames;
}
	
static OUString loader_getImplementationName()
{
    static OUString *pImplName = 0;
    if( ! pImplName )
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if( ! pImplName )
        {
            static OUString implName(
                RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.JavaComponentLoader" ) );
            pImplName = &implName;
        }
    }
    return *pImplName;
}

class JavaComponentLoader : public WeakImplHelper2<XImplementationLoader, XServiceInfo>
{
    css::uno::Reference<XComponentContext> m_xComponentContext;
    /** Do not use m_javaLoader directly. Instead use getJavaLoader.
     */ 
    css::uno::Reference<XImplementationLoader> m_javaLoader;
    /** The retured Reference contains a null pointer if the office is not configured
        to run java.
        
        @exception com::sun::star::uno::RuntimeException
        If the Java implementation of the loader could not be obtained, for reasons other
        then that java was not configured the RuntimeException is thrown.
     */
    const css::uno::Reference<XImplementationLoader> & getJavaLoader();
    
    
public:
	JavaComponentLoader(const css::uno::Reference<XComponentContext> & xCtx)
        throw(RuntimeException);
	virtual ~JavaComponentLoader() throw();

public:
	// XServiceInfo
	virtual OUString SAL_CALL getImplementationName() throw(RuntimeException);
	virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
        throw(RuntimeException);
	virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
        throw(RuntimeException);

	// XImplementationLoader
	virtual css::uno::Reference<XInterface> SAL_CALL activate(
        const OUString& implementationName, const OUString& implementationLoaderUrl,
        const OUString& locationUrl, const css::uno::Reference<XRegistryKey>& xKey)
        throw(CannotActivateFactoryException, RuntimeException);
	virtual sal_Bool SAL_CALL writeRegistryInfo(
        const css::uno::Reference<XRegistryKey>& xKey,
        const OUString& implementationLoaderUrl, const OUString& locationUrl)
        throw(CannotRegisterImplementationException, RuntimeException);
};

const css::uno::Reference<XImplementationLoader> & JavaComponentLoader::getJavaLoader()
{
    MutexGuard aGuard(getInitMutex());

    if (m_javaLoader.is())
        return m_javaLoader;
    
	uno_Environment * pJava_environment = NULL;
	uno_Environment * pUno_environment = NULL;
	typelib_InterfaceTypeDescription * pType_XImplementationLoader = 0;

	try {
		// get a java vm, where we can create a loader
		css::uno::Reference<XJavaVM> javaVM_xJavaVM(
            m_xComponentContext->getValueByName(
                OUString(RTL_CONSTASCII_USTRINGPARAM(
                             "/singletons/"
                             "com.sun.star.java.theJavaVirtualMachine"))),
            UNO_QUERY_THROW);

        // Use the special protocol of XJavaVM.getJavaVM:  If the passed in
        // process ID has an extra 17th byte of value one, the returned any
        // contains a pointer to a jvmaccess::UnoVirtualMachine, instead of the
        // underlying JavaVM pointer:
		Sequence<sal_Int8> processID(17);
		rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8 *>(processID.getArray()));
        processID[16] = 1;

        // We get a non-refcounted pointer to a jvmaccess::UnoVirtualMachine
        // from the XJavaVM service (the pointer is guaranteed to be valid
        // as long as our reference to the XJavaVM service lasts), and
        // convert the non-refcounted pointer into a refcounted one
        // immediately:
        OSL_ENSURE(sizeof (sal_Int64)
                        >= sizeof (jvmaccess::UnoVirtualMachine *),
                    "Pointer cannot be represented as sal_Int64");
        sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
            static_cast< jvmaccess::UnoVirtualMachine * >(0));
        javaVM_xJavaVM->getJavaVM(processID) >>= nPointer;
        rtl::Reference< jvmaccess::UnoVirtualMachine > xVirtualMachine(
            reinterpret_cast< jvmaccess::UnoVirtualMachine * >(nPointer));
        if (!xVirtualMachine.is())
            //throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
            //   "javaloader error - JavaVirtualMachine service could not provide a VM")),
            //   css::uno::Reference<XInterface>());
            // We must not throw a RuntimeException, because this might end the applications.
            // It is ok if java components
            // are not working because the office can be installed without Java support.
            return m_javaLoader; // null-ref

        try
        {
            jvmaccess::VirtualMachine::AttachGuard aGuard2(
                xVirtualMachine->getVirtualMachine());
            JNIEnv * pJNIEnv = aGuard2.getEnvironment();

            // instantiate the java JavaLoader
            jclass jcClassLoader = pJNIEnv->FindClass("java/lang/ClassLoader");
            if(pJNIEnv->ExceptionOccurred())
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - could not find class java/lang/ClassLoader")),
                    css::uno::Reference<XInterface>());
            jmethodID jmLoadClass = pJNIEnv->GetMethodID(
                jcClassLoader, "loadClass",
                "(Ljava/lang/String;)Ljava/lang/Class;");
            if(pJNIEnv->ExceptionOccurred())
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - could not find method java/lang/ClassLoader.loadClass")),
                    css::uno::Reference<XInterface>());
            jvalue arg;
            arg.l = pJNIEnv->NewStringUTF(
                "com.sun.star.comp.loader.JavaLoader");
            if(pJNIEnv->ExceptionOccurred())
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - could not create string")),
                    css::uno::Reference<XInterface>());
            jclass jcJavaLoader = static_cast< jclass >(
                pJNIEnv->CallObjectMethodA(
                    static_cast< jobject >(xVirtualMachine->getClassLoader()),
                    jmLoadClass, &arg));
            if(pJNIEnv->ExceptionOccurred())
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - could not find class com/sun/star/comp/loader/JavaLoader")),
                    css::uno::Reference<XInterface>());
            jmethodID jmJavaLoader_init = pJNIEnv->GetMethodID(jcJavaLoader, "<init>", "()V");
            if(pJNIEnv->ExceptionOccurred())
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed")),
                    css::uno::Reference<XInterface>());
            jobject joJavaLoader = pJNIEnv->NewObject(jcJavaLoader, jmJavaLoader_init);
            if(pJNIEnv->ExceptionOccurred())
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed")),
                    css::uno::Reference<XInterface>());

            // map the java JavaLoader to this environment
            OUString sJava(RTL_CONSTASCII_USTRINGPARAM("java"));
            uno_getEnvironment(&pJava_environment, sJava.pData,
                                xVirtualMachine.get());
            if(!pJava_environment)
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - no Java environment available")), css::uno::Reference<XInterface>());

            // why is there no convinient contructor?
            OUString sCppu_current_lb_name(RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME));
            uno_getEnvironment(&pUno_environment, sCppu_current_lb_name.pData, NULL);
            if(!pUno_environment)
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - no C++ environment available")), css::uno::Reference<XInterface>());

            Mapping java_curr(pJava_environment, pUno_environment);
            if(!java_curr.is())
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - no mapping from java to C++ ")), css::uno::Reference<XInterface>());

            // release java environment
            pJava_environment->release(pJava_environment);
            pJava_environment = NULL;

            // release uno environment
            pUno_environment->release(pUno_environment);
            pUno_environment = NULL;

            getCppuType((css::uno::Reference<XImplementationLoader> *) 0).
                getDescription((typelib_TypeDescription **) & pType_XImplementationLoader);
            if(!pType_XImplementationLoader)
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - no type information for XImplementationLoader")),
                    css::uno::Reference<XInterface>());

            m_javaLoader = css::uno::Reference<XImplementationLoader>(reinterpret_cast<XImplementationLoader *>(
                            java_curr.mapInterface(joJavaLoader, pType_XImplementationLoader)));
            pJNIEnv->DeleteLocalRef( joJavaLoader );
            if(!m_javaLoader.is())
                throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                    "javaloader error - mapping of java XImplementationLoader to c++ failed")),
                    css::uno::Reference<XInterface>());

            typelib_typedescription_release(reinterpret_cast<typelib_TypeDescription *>(pType_XImplementationLoader));
            pType_XImplementationLoader = NULL;
        }
        catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
        {
            throw RuntimeException(
                OUString(RTL_CONSTASCII_USTRINGPARAM(
                                "jvmaccess::VirtualMachine::AttachGuard"
                                "::CreationException")),0);
        }

		// set the service manager at the javaloader
		css::uno::Reference<XInitialization> javaLoader_XInitialization(m_javaLoader, UNO_QUERY);
		if(!javaLoader_XInitialization.is())
            throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
                "javaloader error - initialization of java javaloader failed, no XInitialization")),
                css::uno::Reference<XInterface>());

		Any any;
		any <<= css::uno::Reference<XMultiComponentFactory>(
            m_xComponentContext->getServiceManager());

		javaLoader_XInitialization->initialize(Sequence<Any>(&any, 1));
	}
	catch(RuntimeException &) {
		if(pJava_environment)
			pJava_environment->release(pJava_environment);

		if(pUno_environment)
			pUno_environment->release(pUno_environment);

		if(pType_XImplementationLoader)
			typelib_typedescription_release(
                reinterpret_cast<typelib_TypeDescription *>(pType_XImplementationLoader));
		throw;
	}
	OSL_TRACE("javaloader.cxx: mapped javaloader - 0x%x", m_javaLoader.get());
    return m_javaLoader;
}

JavaComponentLoader::JavaComponentLoader(const css::uno::Reference<XComponentContext> & xCtx) throw(RuntimeException) :
    m_xComponentContext(xCtx)
    
{

}

JavaComponentLoader::~JavaComponentLoader() throw()
{
}

// XServiceInfo
OUString SAL_CALL JavaComponentLoader::getImplementationName()
    throw(::com::sun::star::uno::RuntimeException)
{
	return loader_getImplementationName();	
}	

sal_Bool SAL_CALL JavaComponentLoader::supportsService(const OUString & ServiceName)
    throw(::com::sun::star::uno::RuntimeException)
{
	sal_Bool bSupport = sal_False;

	Sequence<OUString> aSNL = getSupportedServiceNames();
	const OUString * pArray = aSNL.getArray();
	for(sal_Int32 i = 0; i < aSNL.getLength() && !bSupport; ++ i)
		bSupport = pArray[i] == ServiceName;

	return bSupport;
}	

Sequence<OUString> SAL_CALL JavaComponentLoader::getSupportedServiceNames()
    throw(::com::sun::star::uno::RuntimeException)
{
	return loader_getSupportedServiceNames();
}



// XImplementationLoader
sal_Bool SAL_CALL JavaComponentLoader::writeRegistryInfo(
    const css::uno::Reference<XRegistryKey> & xKey, const OUString & blabla,
    const OUString & rLibName)
	throw(CannotRegisterImplementationException, RuntimeException)
{
    const css::uno::Reference<XImplementationLoader> & loader = getJavaLoader();
    if (loader.is())
        return loader->writeRegistryInfo(xKey, blabla, rLibName);
    else
        throw CannotRegisterImplementationException(
            OUString(RTL_CONSTASCII_USTRINGPARAM("Could not create Java implementation loader")), NULL);
}


css::uno::Reference<XInterface> SAL_CALL JavaComponentLoader::activate(
    const OUString & rImplName, const OUString & blabla, const OUString & rLibName,
    const css::uno::Reference<XRegistryKey> & xKey)
    throw(CannotActivateFactoryException, RuntimeException)
{
    const css::uno::Reference<XImplementationLoader> & loader = getJavaLoader();
    if (loader.is())
        return loader->activate(rImplName, blabla, rLibName, xKey);
    else
        throw CannotActivateFactoryException(
            OUString(RTL_CONSTASCII_USTRINGPARAM("Could not create Java implementation loader")), NULL);
}

static Mutex & getInitMutex()
{
    static Mutex * pMutex = 0;
    if( ! pMutex )
    {
        MutexGuard guard( Mutex::getGlobalMutex() );
        if( ! pMutex )
        {
            static Mutex mutex;
            pMutex = &mutex;
        }
    }
    return *pMutex;
}

css::uno::Reference<XInterface> SAL_CALL JavaComponentLoader_CreateInstance(const css::uno::Reference<XComponentContext> & xCtx) throw(Exception)
{
    css::uno::Reference<XInterface> xRet;
    
    try {
        MutexGuard guard( getInitMutex() );
        // The javaloader is never destroyed and there can be only one!
        // Note that the first context wins ....
        static css::uno::Reference< XInterface > *pStaticRef = 0;
        if( pStaticRef )
        {
            xRet = *pStaticRef;
        }
        else
        {
            xRet = *new JavaComponentLoader(xCtx);
            pStaticRef = new css::uno::Reference< XInterface > ( xRet );
        }
    }
    catch(RuntimeException & runtimeException) {
        OString message = OUStringToOString(runtimeException.Message, RTL_TEXTENCODING_ASCII_US);
        osl_trace("javaloader - could not init javaloader cause of %s", message.getStr());
        throw;
    }
    
    return xRet;
}

} //end namespace


using namespace stoc_javaloader;

static struct ImplementationEntry g_entries[] =
{
	{
		JavaComponentLoader_CreateInstance, loader_getImplementationName,
		loader_getSupportedServiceNames, createSingleComponentFactory,
		0 , 0
	},
	{ 0, 0, 0, 0, 0, 0 }
};

extern "C"
{
// NOTE: component_canUnload is not exported, as the library cannot be unloaded.

//==================================================================================================
void SAL_CALL component_getImplementationEnvironment(
	const sal_Char ** ppEnvTypeName, uno_Environment ** )
{
	*ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
}
//==================================================================================================
void * SAL_CALL component_getFactory(
	const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
{
	return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
}
}
