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

#include "dispatchwatcher.hxx"
#include <rtl/ustring.hxx>
#include <tools/string.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/synchronousdispatch.hxx>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/util/CloseVetoException.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/util/URL.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/container/XEnumeration.hpp>
#include <com/sun/star/frame/XFramesSupplier.hpp>
#include <com/sun/star/frame/XDispatch.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/view/XPrintable.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/document/UpdateDocMode.hpp>

#include <tools/urlobj.hxx>
#include <comphelper/mediadescriptor.hxx>

#include <vector>

using namespace ::rtl;
using namespace ::osl;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::view;

namespace desktop
{

String GetURL_Impl(
    const String& rName, boost::optional< rtl::OUString > const & cwdUrl );

struct DispatchHolder
{
	DispatchHolder( const URL& rURL, Reference< XDispatch >& rDispatch ) :
		aURL( rURL ), xDispatch( rDispatch ) {}

	URL	aURL;
    rtl::OUString cwdUrl;
	Reference< XDispatch > xDispatch;
};

Mutex* DispatchWatcher::pWatcherMutex = NULL;

Mutex& DispatchWatcher::GetMutex()
{
	if ( !pWatcherMutex )
	{
		::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
		if ( !pWatcherMutex )
			pWatcherMutex = new osl::Mutex();
	}

	return *pWatcherMutex;
}

// Create or get the dispatch watcher implementation. This implementation must be
// a singleton to prevent access to the framework after it wants to terminate.
DispatchWatcher* DispatchWatcher::GetDispatchWatcher()
{
    static Reference< XInterface > xDispatchWatcher;
    static DispatchWatcher*        pDispatchWatcher = NULL;

    if ( !xDispatchWatcher.is() )
	{
		::osl::MutexGuard aGuard( GetMutex() );

		if ( !xDispatchWatcher.is() )
        {
			pDispatchWatcher = new DispatchWatcher();

            // We have to hold a reference to ourself forever to prevent our own destruction.
            xDispatchWatcher = static_cast< cppu::OWeakObject *>( pDispatchWatcher );
        }
	}

    return pDispatchWatcher;
}


DispatchWatcher::DispatchWatcher()
    : m_nRequestCount(0)
{
}


DispatchWatcher::~DispatchWatcher()
{
}


sal_Bool DispatchWatcher::executeDispatchRequests( const DispatchList& aDispatchRequestsList, bool bNoTerminate )
{
    Reference< XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(
												OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
											UNO_QUERY );

	DispatchList::const_iterator	p;
	std::vector< DispatchHolder >	aDispatches;
	::rtl::OUString					aAsTemplateArg( RTL_CONSTASCII_USTRINGPARAM( "AsTemplate"));

	for ( p = aDispatchRequestsList.begin(); p != aDispatchRequestsList.end(); p++ )
	{
        String					aPrinterName;
		const DispatchRequest&	aDispatchRequest = *p;

        // create parameter array
        sal_Int32 nCount = 4;
        if ( aDispatchRequest.aPreselectedFactory.getLength() )
            nCount++;

		// we need more properties for a print/print to request
		if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
			 aDispatchRequest.aRequestType == REQUEST_PRINTTO  )
            nCount++;

        Sequence < PropertyValue > aArgs( nCount );

        // mark request as user interaction from outside
        aArgs[0].Name = ::rtl::OUString::createFromAscii("Referer");
        aArgs[0].Value <<= ::rtl::OUString::createFromAscii("private:OpenEvent");

        if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
			 aDispatchRequest.aRequestType == REQUEST_PRINTTO )
        {
            aArgs[1].Name = ::rtl::OUString::createFromAscii("ReadOnly");
            aArgs[2].Name = ::rtl::OUString::createFromAscii("OpenNewView");
            aArgs[3].Name = ::rtl::OUString::createFromAscii("Hidden");
            aArgs[4].Name = ::rtl::OUString::createFromAscii("Silent");
        }
        else
        {
            Reference < com::sun::star::task::XInteractionHandler > xInteraction(
                ::comphelper::getProcessServiceFactory()->createInstance( OUString::createFromAscii("com.sun.star.task.InteractionHandler") ),
                com::sun::star::uno::UNO_QUERY );

            aArgs[1].Name = OUString::createFromAscii( "InteractionHandler" );
            aArgs[1].Value <<= xInteraction;

			sal_Int16 nMacroExecMode = ::com::sun::star::document::MacroExecMode::USE_CONFIG;
            aArgs[2].Name = OUString::createFromAscii( "MacroExecutionMode" );
            aArgs[2].Value <<= nMacroExecMode;

			sal_Int16 nUpdateDoc = ::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG;
            aArgs[3].Name = OUString::createFromAscii( "UpdateDocMode" );
            aArgs[3].Value <<= nUpdateDoc;
        }

        if ( aDispatchRequest.aPreselectedFactory.getLength() )
        {
            aArgs[nCount-1].Name = ::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE();
            aArgs[nCount-1].Value <<= aDispatchRequest.aPreselectedFactory;
        }

        String aName( GetURL_Impl( aDispatchRequest.aURL, aDispatchRequest.aCwdUrl ) );
        ::rtl::OUString aTarget( RTL_CONSTASCII_USTRINGPARAM("_default") );

        if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
			 aDispatchRequest.aRequestType == REQUEST_PRINTTO )
        {
            // documents opened for printing are opened readonly because they must be opened as a new document and this
            // document could be open already
            aArgs[1].Value <<= sal_True;

            // always open a new document for printing, because it must be disposed afterwards
            aArgs[2].Value <<= sal_True;

            // printing is done in a hidden view
            aArgs[3].Value <<= sal_True;

            // load document for printing without user interaction
            aArgs[4].Value <<= sal_True;

            // hidden documents should never be put into open tasks
            aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_blank") );
        }

        // load the document ... if they are loadable!
        // Otherwise try to dispatch it ...
        Reference < XPrintable > xDoc;
        if(
            ( aName.CompareToAscii( ".uno"  , 4 ) == COMPARE_EQUAL )  ||
            ( aName.CompareToAscii( "slot:" , 5 ) == COMPARE_EQUAL )  ||
            ( aName.CompareToAscii( "macro:", 6 ) == COMPARE_EQUAL )  ||
            ( aName.CompareToAscii("vnd.sun.star.script", 19) == COMPARE_EQUAL)
          )
        {
            // Attention: URL must be parsed full. Otherwise some detections on it will fail!
            // It doesn't matter, if parser isn't available. Because; We try loading of URL then ...
            URL             aURL ;
            aURL.Complete = aName;

            Reference < XDispatch >         xDispatcher ;
            Reference < XDispatchProvider > xProvider   ( xDesktop, UNO_QUERY );
            Reference < XURLTransformer >   xParser     ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );

            if( xParser.is() == sal_True )
                xParser->parseStrict( aURL );

            if( xProvider.is() == sal_True )
                xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );

            if( xDispatcher.is() == sal_True )
			{
				{
					::osl::ClearableMutexGuard aGuard( GetMutex() );
					// Remember request so we can find it in statusChanged!
					m_aRequestContainer.insert( DispatchWatcherHashMap::value_type( aURL.Complete, (sal_Int32)1 ) );
                    m_nRequestCount++;
				}

				// Use local vector to store dispatcher because we have to fill our request container before
				// we can dispatch. Otherwise it would be possible that statusChanged is called before we dispatched all requests!!
				aDispatches.push_back( DispatchHolder( aURL, xDispatcher ));
			}
        }
        else if ( ( aName.CompareToAscii( "service:"  , 8 ) == COMPARE_EQUAL ) )
        {
            // TODO: the dispatch has to be done for loadComponentFromURL as well. Please ask AS for more details.
            URL             aURL ;
            aURL.Complete = aName;

            Reference < XDispatch >         xDispatcher ;
            Reference < XDispatchProvider > xProvider   ( xDesktop, UNO_QUERY );
            Reference < XURLTransformer >   xParser     ( ::comphelper::getProcessServiceFactory()->createInstance( OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer")) ), ::com::sun::star::uno::UNO_QUERY );

            if( xParser.is() == sal_True )
                xParser->parseStrict( aURL );

            if( xProvider.is() == sal_True )
                xDispatcher = xProvider->queryDispatch( aURL, ::rtl::OUString(), 0 );

            if( xDispatcher.is() == sal_True )
            {
			    try
			    {
				    // We have to be listener to catch errors during dispatching URLs.
				    // Otherwise it would be possible to have an office running without an open
				    // window!!
                    Sequence < PropertyValue > aArgs2(1);
                    aArgs2[0].Name    = ::rtl::OUString::createFromAscii("SynchronMode");
                    aArgs2[0].Value <<= sal_True;
				    Reference < XNotifyingDispatch > xDisp( xDispatcher, UNO_QUERY );
				    if ( xDisp.is() )
					    xDisp->dispatchWithNotification( aURL, aArgs2, DispatchWatcher::GetDispatchWatcher() );
				    else
					    xDispatcher->dispatch( aURL, aArgs2 );
			    }
			    catch ( ::com::sun::star::uno::Exception& )
			    {
				    OUString aMsg = OUString::createFromAscii(
					    "Desktop::OpenDefault() IllegalArgumentException while calling XNotifyingDispatch: ");
				    OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
			    }
            }
        }
        else
        {
            INetURLObject aObj( aName );
            if ( aObj.GetProtocol() == INET_PROT_PRIVATE )
                aTarget = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_default") );

			// Set "AsTemplate" argument according to request type
            if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW ||
				 aDispatchRequest.aRequestType == REQUEST_FORCEOPEN		)
			{
				sal_Int32 nIndex = aArgs.getLength();
				aArgs.realloc( nIndex+1 );
				aArgs[nIndex].Name = aAsTemplateArg;
				if ( aDispatchRequest.aRequestType == REQUEST_FORCENEW )
					aArgs[nIndex].Value <<= sal_True;
				else
					aArgs[nIndex].Value <<= sal_False;
			}

			// if we are called in viewmode, open document read-only
			// #95425#
			if(aDispatchRequest.aRequestType == REQUEST_VIEW) {
				sal_Int32 nIndex = aArgs.getLength();
				aArgs.realloc(nIndex+1);
				aArgs[nIndex].Name = OUString::createFromAscii("ReadOnly");
				aArgs[nIndex].Value <<= sal_True;
			}

            // if we are called with -start set Start in mediadescriptor
			if(aDispatchRequest.aRequestType == REQUEST_START) {
				sal_Int32 nIndex = aArgs.getLength();
				aArgs.realloc(nIndex+1);
				aArgs[nIndex].Name = OUString::createFromAscii("StartPresentation");
				aArgs[nIndex].Value <<= sal_True;
			}

			// This is a synchron loading of a component so we don't have to deal with our statusChanged listener mechanism.

            try
            {
                xDoc = Reference < XPrintable >( ::comphelper::SynchronousDispatch::dispatch( xDesktop, aName, aTarget, 0, aArgs ), UNO_QUERY );
                //xDoc = Reference < XPrintable >( xDesktop->loadComponentFromURL( aName, aTarget, 0, aArgs ), UNO_QUERY );
            }
            catch ( ::com::sun::star::lang::IllegalArgumentException& iae)
            {
                OUString aMsg = OUString::createFromAscii(
                    "Dispatchwatcher IllegalArgumentException while calling loadComponentFromURL: ")
                    + iae.Message;
                OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
            }
            catch (com::sun::star::io::IOException& ioe)
            {
                OUString aMsg = OUString::createFromAscii(
                    "Dispatchwatcher IOException while calling loadComponentFromURL: ")
                    + ioe.Message;
                OSL_ENSURE( sal_False, OUStringToOString(aMsg, RTL_TEXTENCODING_ASCII_US).getStr());
            }
			if ( aDispatchRequest.aRequestType == REQUEST_OPEN ||
				 aDispatchRequest.aRequestType == REQUEST_VIEW ||
                 aDispatchRequest.aRequestType == REQUEST_START ||
				 aDispatchRequest.aRequestType == REQUEST_FORCEOPEN ||
				 aDispatchRequest.aRequestType == REQUEST_FORCENEW		)
			{
				// request is completed
				OfficeIPCThread::RequestsCompleted( 1 );
			}
			else if ( aDispatchRequest.aRequestType == REQUEST_PRINT ||
					  aDispatchRequest.aRequestType == REQUEST_PRINTTO )
			{
				if ( xDoc.is() )
				{
					if ( aDispatchRequest.aRequestType == REQUEST_PRINTTO )
					{
						// create the printer
						Sequence < PropertyValue > aPrinterArgs( 1 );
						aPrinterArgs[0].Name = ::rtl::OUString::createFromAscii("Name");
						aPrinterArgs[0].Value <<= ::rtl::OUString( aDispatchRequest.aPrinterName );
						xDoc->setPrinter( aPrinterArgs );
					}

					// print ( also without user interaction )
					Sequence < PropertyValue > aPrinterArgs( 1 );
					aPrinterArgs[0].Name = ::rtl::OUString::createFromAscii("Wait");
					aPrinterArgs[0].Value <<= ( sal_Bool ) sal_True;
					xDoc->print( aPrinterArgs );
				}
				else
				{
					// place error message here ...
				}

				// remove the document
				try
				{
					Reference < XCloseable > xClose( xDoc, UNO_QUERY );
					if ( xClose.is() )
						xClose->close( sal_True );
					else
					{
						Reference < XComponent > xComp( xDoc, UNO_QUERY );
						if ( xComp.is() )
							xComp->dispose();
					}
				}
				catch ( com::sun::star::util::CloseVetoException& )
				{
				}

				// request is completed
				OfficeIPCThread::RequestsCompleted( 1 );
			}
		}
	}

    if ( aDispatches.size() > 0 )
	{
		// Execute all asynchronous dispatches now after we placed them into our request container!
		Sequence < PropertyValue > aArgs( 2 );
		aArgs[0].Name = ::rtl::OUString::createFromAscii("Referer");
        aArgs[0].Value <<= ::rtl::OUString::createFromAscii("private:OpenEvent");
		aArgs[1].Name = ::rtl::OUString::createFromAscii("SynchronMode");
        aArgs[1].Value <<= sal_True;

		for ( sal_uInt32 n = 0; n < aDispatches.size(); n++ )
		{
			Reference< XDispatch > xDispatch = aDispatches[n].xDispatch;
            Reference < XNotifyingDispatch > xDisp( xDispatch, UNO_QUERY );
            if ( xDisp.is() )
                xDisp->dispatchWithNotification( aDispatches[n].aURL, aArgs, this );
            else
            {
                ::osl::ClearableMutexGuard aGuard( GetMutex() );
                m_nRequestCount--;
                aGuard.clear();
                xDispatch->dispatch( aDispatches[n].aURL, aArgs );
            }
		}
	}

	::osl::ClearableMutexGuard aGuard( GetMutex() );
    bool bEmpty = (m_nRequestCount == 0);
    aGuard.clear();

	// No more asynchronous requests?
	// The requests are removed from the request container after they called back to this
	// implementation via statusChanged!!
    if ( bEmpty && !bNoTerminate /*m_aRequestContainer.empty()*/ )
	{
		// We have to check if we have an open task otherwise we have to shutdown the office.
        Reference< XFramesSupplier > xTasksSupplier( xDesktop, UNO_QUERY );
        aGuard.clear();

        Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );

        if ( !xList->hasElements() )
		{
			// We don't have any task open so we have to shutdown ourself!!
			Reference< XDesktop > xDesktop2( xTasksSupplier, UNO_QUERY );
			if ( xDesktop2.is() )
				return xDesktop2->terminate();
		}
	}

	return sal_False;
}


void SAL_CALL DispatchWatcher::disposing( const ::com::sun::star::lang::EventObject& )
throw(::com::sun::star::uno::RuntimeException)
{
}


void SAL_CALL DispatchWatcher::dispatchFinished( const DispatchResultEvent& ) throw( RuntimeException )
{
	osl::ClearableMutexGuard aGuard( GetMutex() );
    sal_Int16 nCount = --m_nRequestCount;
    aGuard.clear();
    OfficeIPCThread::RequestsCompleted( 1 );
/*
	// Find request in our hash map and remove it as a pending request
    DispatchWatcherHashMap::iterator pDispatchEntry = m_aRequestContainer.find( rEvent.FeatureURL.Complete ) ;
    if ( pDispatchEntry != m_aRequestContainer.end() )
	{
        m_aRequestContainer.erase( pDispatchEntry );
        aGuard.clear();
		OfficeIPCThread::RequestsCompleted( 1 );
	}
	else
		aGuard.clear();
*/
    if ( !nCount && !OfficeIPCThread::AreRequestsPending() )
	{
		// We have to check if we have an open task otherwise we have to shutdown the office.
        Reference< XFramesSupplier > xTasksSupplier( ::comphelper::getProcessServiceFactory()->createInstance(
													OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop")) ),
												UNO_QUERY );
        Reference< XElementAccess > xList( xTasksSupplier->getFrames(), UNO_QUERY );

        if ( !xList->hasElements() )
		{
			// We don't have any task open so we have to shutdown ourself!!
			Reference< XDesktop > xDesktop( xTasksSupplier, UNO_QUERY );
			if ( xDesktop.is() )
				xDesktop->terminate();
		}
	}
}

}
