/*
 * 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.
 */

#ifndef _LOG4CXX_ASYNC_APPENDER_H
#define _LOG4CXX_ASYNC_APPENDER_H

#if defined(_MSC_VER)
    #pragma warning ( push )
    #pragma warning ( disable: 4231 4251 4275 4786 )
#endif


#include <log4cxx/appenderskeleton.h>
#include <log4cxx/helpers/appenderattachableimpl.h>
#include <deque>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/helpers/thread.h>
#include <log4cxx/helpers/mutex.h>
#include <log4cxx/helpers/condition.h>

#if defined(NON_BLOCKING)
    #include <boost/lockfree/queue.hpp>
#endif

namespace log4cxx
{
LOG4CXX_LIST_DEF(LoggingEventList, log4cxx::spi::LoggingEventPtr);

/**
The AsyncAppender lets users log events asynchronously. It uses a
bounded buffer to store logging events.

<p>The AsyncAppender will collect the events sent to it and then
dispatch them to all the appenders that are attached to it. You can
attach multiple appenders to an AsyncAppender.

<p>The AsyncAppender uses a separate thread to serve the events in
its bounded buffer.

<p><b>Important note:</b> The <code>AsyncAppender</code> can only
be script configured using the {@link xml::DOMConfigurator DOMConfigurator}.
*/
class LOG4CXX_EXPORT AsyncAppender :
    public virtual spi::AppenderAttachable,
    public virtual AppenderSkeleton
{
    public:
        DECLARE_LOG4CXX_OBJECT(AsyncAppender)
        BEGIN_LOG4CXX_CAST_MAP()
        LOG4CXX_CAST_ENTRY(AsyncAppender)
        LOG4CXX_CAST_ENTRY_CHAIN(AppenderSkeleton)
        LOG4CXX_CAST_ENTRY(spi::AppenderAttachable)
        END_LOG4CXX_CAST_MAP()

        /**
         * Create new instance.
        */
        AsyncAppender();

        /**
         *  Destructor.
         */
        virtual ~AsyncAppender();

        void addRef() const;
        void releaseRef() const;

        /**
         * Add appender.
         *
         * @param newAppender appender to add, may not be null.
        */
        void addAppender(const AppenderPtr& newAppender);

        virtual void doAppend(const spi::LoggingEventPtr& event,
                              log4cxx::helpers::Pool& pool1);

        void append(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p);

        /**
        Close this <code>AsyncAppender</code> by interrupting the
        dispatcher thread which will process all pending events before
        exiting.
        */
        void close();

        /**
         * Get iterator over attached appenders.
         * @return list of all attached appenders.
        */
        AppenderList getAllAppenders() const;

        /**
         * Get appender by name.
         *
         * @param name name, may not be null.
         * @return matching appender or null.
        */
        AppenderPtr getAppender(const LogString& name) const;

        /**
         * Gets whether the location of the logging request call
         * should be captured.
         *
         * @return the current value of the <b>LocationInfo</b> option.
        */
        bool getLocationInfo() const;
        /**
        * Determines if specified appender is attached.
        * @param appender appender.
        * @return true if attached.
        */
        bool isAttached(const AppenderPtr& appender) const;

        virtual bool requiresLayout() const;

        /**
         * Removes and closes all attached appenders.
        */
        void removeAllAppenders();

        /**
         * Removes an appender.
         * @param appender appender to remove.
        */
        void removeAppender(const AppenderPtr& appender);
        /**
        * Remove appender by name.
        * @param name name.
        */
        void removeAppender(const LogString& name);

        /**
        * The <b>LocationInfo</b> attribute is provided for compatibility
        * with log4j and has no effect on the log output.
        * @param flag new value.
        */
        void setLocationInfo(bool flag);

        /**
        * The <b>BufferSize</b> option takes a non-negative integer value.
        * This integer value determines the maximum size of the bounded
        * buffer.
        * */
        void setBufferSize(int size);

        /**
         * Gets the current buffer size.
         * @return the current value of the <b>BufferSize</b> option.
        */
        int getBufferSize() const;

        /**
         * Sets whether appender should wait if there is no
         * space available in the event buffer or immediately return.
         *
         * @param value true if appender should wait until available space in buffer.
         */
        void setBlocking(bool value);

        /**
         * Gets whether appender should block calling thread when buffer is full.
         * If false, messages will be counted by logger and a summary
         * message appended after the contents of the buffer have been appended.
         *
         * @return true if calling thread will be blocked when buffer is full.
         */
        bool getBlocking() const;


        /**
         * Set appender properties by name.
         * @param option property name.
         * @param value property value.
         */
        void setOption(const LogString& option, const LogString& value);


    private:
        AsyncAppender(const AsyncAppender&);
        AsyncAppender& operator=(const AsyncAppender&);
        /**
         * The default buffer size is set to 128 events.
        */
        enum { DEFAULT_BUFFER_SIZE = 128 };

        /**
         * Event buffer.
        */
#if defined(NON_BLOCKING)
        boost::lockfree::queue<log4cxx::spi::LoggingEvent* > buffer;
        std::atomic<size_t> discardedCount;
#else
        LoggingEventList buffer;
#endif

        /**
         *  Mutex used to guard access to buffer and discardMap.
         */
        SHARED_MUTEX bufferMutex;

#if defined(NON_BLOCKING)
        ::log4cxx::helpers::Semaphore bufferNotFull;
        ::log4cxx::helpers::Semaphore bufferNotEmpty;
#else
        ::log4cxx::helpers::Condition bufferNotFull;
        ::log4cxx::helpers::Condition bufferNotEmpty;
#endif
        class DiscardSummary
        {
            private:
                /**
                 * First event of the highest severity.
                */
                ::log4cxx::spi::LoggingEventPtr maxEvent;

                /**
                * Total count of messages discarded.
                */
                int count;

            public:
                /**
                 * Create new instance.
                 *
                 * @param event event, may not be null.
                */
                DiscardSummary(const ::log4cxx::spi::LoggingEventPtr& event);
                /** Copy constructor.  */
                DiscardSummary(const DiscardSummary& src);
                /** Assignment operator. */
                DiscardSummary& operator=(const DiscardSummary& src);

                /**
                 * Add discarded event to summary.
                 *
                 * @param event event, may not be null.
                */
                void add(const ::log4cxx::spi::LoggingEventPtr& event);

                /**
                 * Create event with summary information.
                 *
                 * @return new event.
                 */
                ::log4cxx::spi::LoggingEventPtr createEvent(::log4cxx::helpers::Pool& p);

                static
                ::log4cxx::spi::LoggingEventPtr createEvent(::log4cxx::helpers::Pool& p,
                        size_t discardedCount);
        };

        /**
          * Map of DiscardSummary objects keyed by logger name.
        */
        typedef std::map<LogString, DiscardSummary> DiscardMap;
        DiscardMap* discardMap;

        /**
         * Buffer size.
        */
        int bufferSize;

        /**
         * Nested appenders.
        */
        helpers::AppenderAttachableImplPtr appenders;

        /**
         *  Dispatcher.
         */
        helpers::Thread dispatcher;

        /**
         * Should location info be included in dispatched messages.
        */
        bool locationInfo;

        /**
         * Does appender block when buffer is full.
        */
        bool blocking;

        /**
         *  Dispatch routine.
         */
        static void* LOG4CXX_THREAD_FUNC dispatch(apr_thread_t* thread, void* data);

}; // class AsyncAppender
LOG4CXX_PTR_DEF(AsyncAppender);
}  //  namespace log4cxx

#if defined(_MSC_VER)
    #pragma warning ( pop )
#endif


#endif//  _LOG4CXX_ASYNC_APPENDER_H

