/**************************************************************
 *
 * 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 shutting 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 shutting 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 shutting 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 shutting 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 shutting 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 shutting 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;
}
