/**************************************************************
 * 
 * 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_sw.hxx"
#include "maildispatcher.hxx"
#include "imaildsplistener.hxx"

#include <algorithm>

using namespace ::com::sun::star;
using ::rtl::OUString;

typedef std::list< uno::Reference<mail::XMailMessage> > MailMessageContainer_t;
typedef std::list< ::rtl::Reference<IMailDispatcherListener> > MailDispatcherListenerContainer_t;

namespace /* private */
{
    /* Generic event notifier for started, 
       stopped, and idle events which are 
       very similary */
    class GenericEventNotifier
    {
    public:
        // pointer to virtual function typedef
        typedef void (IMailDispatcherListener::*GenericNotificationFunc_t)(::rtl::Reference<MailDispatcher>);
        
        GenericEventNotifier(
            GenericNotificationFunc_t notification_function, 
            ::rtl::Reference<MailDispatcher> mail_dispatcher) :
            notification_function_(notification_function),
            mail_dispatcher_(mail_dispatcher)
        {}
        
        void operator() (::rtl::Reference<IMailDispatcherListener> listener) const
        { (listener.get()->*notification_function_)(mail_dispatcher_); }
                        
    private:
        GenericNotificationFunc_t notification_function_;
        ::rtl::Reference<MailDispatcher> mail_dispatcher_;
    };
                                           
    class MailDeliveryNotifier
    {
    public:
        MailDeliveryNotifier(::rtl::Reference<MailDispatcher> xMailDispatcher, uno::Reference<mail::XMailMessage> message) :
            mail_dispatcher_(xMailDispatcher),
            message_(message)
        {}
        
        void operator() (::rtl::Reference<IMailDispatcherListener> listener) const
        { listener->mailDelivered(mail_dispatcher_, message_); }        
        
    private:
        ::rtl::Reference<MailDispatcher> mail_dispatcher_;
        uno::Reference<mail::XMailMessage> message_;
    };
    
    class MailDeliveryErrorNotifier
    {
    public:
        MailDeliveryErrorNotifier(
            ::rtl::Reference<MailDispatcher> xMailDispatcher,
            uno::Reference<mail::XMailMessage> message, 
            const ::rtl::OUString& error_message) : 
            mail_dispatcher_(xMailDispatcher),
            message_(message),
            error_message_(error_message)
        {}
        
        void operator() (::rtl::Reference<IMailDispatcherListener> listener) const
        { listener->mailDeliveryError(mail_dispatcher_, message_, error_message_); }
                
    private:
        ::rtl::Reference<MailDispatcher> mail_dispatcher_;
        uno::Reference<mail::XMailMessage> message_;
        ::rtl::OUString error_message_;
    };
    
} // namespace private

    
MailDispatcher::MailDispatcher(uno::Reference<mail::XSmtpService> mailserver) :
    mailserver_ (mailserver),
    run_(false),    
    shutdown_requested_(false)
{            
    wakening_call_.reset();
    mail_dispatcher_active_.reset();
    
    if (!create())        
        throw uno::RuntimeException();   
    
    // wait until the mail dispatcher thread is really alive    
    // and has acquired a reference to this instance of the 
    // class    
    mail_dispatcher_active_.wait();                                             
}

MailDispatcher::~MailDispatcher()
{    
}

void MailDispatcher::enqueueMailMessage(uno::Reference<mail::XMailMessage> message)
{   
    ::osl::MutexGuard thread_status_guard(thread_status_mutex_);     
    ::osl::MutexGuard message_container_guard(message_container_mutex_);
    
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");
        
    messages_.push_back(message);                    
    if (run_)
        wakening_call_.set();             
}

uno::Reference<mail::XMailMessage> MailDispatcher::dequeueMailMessage()
{        
    ::osl::MutexGuard guard(message_container_mutex_);
    uno::Reference<mail::XMailMessage> message;
    if(!messages_.empty())
    {        
        message = messages_.front();
        messages_.pop_front();
    }
    return message;
}

void MailDispatcher::start()
{            
    OSL_PRECOND(!isStarted(), "MailDispatcher is already started!");    
    
    ::osl::ClearableMutexGuard thread_status_guard(thread_status_mutex_);        
        
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");
    
    if (!shutdown_requested_)
    {
        run_ = true;
        wakening_call_.set();
        thread_status_guard.clear();
        
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());    
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), GenericEventNotifier(&IMailDispatcherListener::started, this));        
    }        
}

void MailDispatcher::stop()
{
    OSL_PRECOND(isStarted(), "MailDispatcher not started!");    
    
    ::osl::ClearableMutexGuard thread_status_guard(thread_status_mutex_);                
        
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");
    
    if (!shutdown_requested_)
    {
        run_ = false;
        wakening_call_.reset();
        thread_status_guard.clear();
        
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());    
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), GenericEventNotifier(&IMailDispatcherListener::stopped, this));   
    }
}

void MailDispatcher::shutdown()
{        
    ::osl::MutexGuard thread_status_guard(thread_status_mutex_);            
    
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");
    
    shutdown_requested_ = true;
    wakening_call_.set();        
}

bool MailDispatcher::isStarted() const
{
    return run_;
}

void MailDispatcher::addListener(::rtl::Reference<IMailDispatcherListener> listener)
{
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");
    
    ::osl::MutexGuard guard(listener_container_mutex_);
    listeners_.push_back(listener);
}

void MailDispatcher::removeListener(::rtl::Reference<IMailDispatcherListener> listener)
{
    OSL_PRECOND(!shutdown_requested_, "MailDispatcher thread is shuting down already");
    
    ::osl::MutexGuard guard(listener_container_mutex_);
    listeners_.remove(listener);
}

std::list< ::rtl::Reference<IMailDispatcherListener> > MailDispatcher::cloneListener()
{
    ::osl::MutexGuard guard(listener_container_mutex_);
    return listeners_;
}

void MailDispatcher::sendMailMessageNotifyListener(uno::Reference<mail::XMailMessage> message)
{
    try
    {
        mailserver_->sendMailMessage(message);                        
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());            
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), MailDeliveryNotifier(this, message));                   
    }
    catch (mail::MailException& ex)
    {            
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());            
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), MailDeliveryErrorNotifier(this, message, ex.Message));                   
    }
    catch (uno::RuntimeException& ex)
    {   
        MailDispatcherListenerContainer_t listeners_cloned(cloneListener());            
        std::for_each(listeners_cloned.begin(), listeners_cloned.end(), MailDeliveryErrorNotifier(this, message, ex.Message));                   
    }
}

void MailDispatcher::run()
{    
    // acquire a self reference in order to avoid race
    // conditions. The last client of this class must
    // call shutdown before releasing his last reference 
    // to this class in order to shutdown this thread
    // which will release his (the very last reference
    // to the class and so force their destruction        
    m_xSelfReference = this; 
    
    // signal that the mail dispatcher thread is now alive
    mail_dispatcher_active_.set();
    
    for(;;)
    {       
        wakening_call_.wait();
                                                                                                                            
        ::osl::ClearableMutexGuard thread_status_guard(thread_status_mutex_);        
        if (shutdown_requested_)
           break;
    
        ::osl::ClearableMutexGuard message_container_guard(message_container_mutex_);
                   
        if (messages_.size())
        {   
            thread_status_guard.clear();         
            uno::Reference<mail::XMailMessage> message = messages_.front();
            messages_.pop_front();
            message_container_guard.clear();
            sendMailMessageNotifyListener(message);
        }
        else // idle - put ourself to sleep 
        {
            wakening_call_.reset();
            message_container_guard.clear();
            thread_status_guard.clear();
            MailDispatcherListenerContainer_t listeners_cloned(cloneListener());    
            std::for_each(listeners_cloned.begin(), listeners_cloned.end(), GenericEventNotifier(&IMailDispatcherListener::idle, this));               
        }                                                    
    } // end for        SSH ALI
}
/*-- 27.08.2004 12:04:46---------------------------------------------------

  -----------------------------------------------------------------------*/
void MailDispatcher::onTerminated() 
{
    //keep the reference until the end of onTerminated() because of the call order in the 
    //_threadFunc() from osl/thread.hxx
    m_xSelfReference = 0;
}
