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

#if !defined(_LOG4CXX_ROLLING_ROLLING_FILE_APPENDER_SKELETON_H)
#define _LOG4CXX_ROLLING_ROLLING_FILE_APPENDER_SKELETON_H

#include <log4cxx/portability.h>
#include <log4cxx/spi/optionhandler.h>
#include <log4cxx/fileappender.h>
#include <log4cxx/rolling/triggeringpolicy.h>
#include <log4cxx/rolling/rollingpolicy.h>
#include <log4cxx/rolling/action.h>

namespace log4cxx {
    namespace rolling {


        /**
         *  Base class for log4cxx::rolling::RollingFileAppender and log4cxx::RollingFileAppender
         * (analogues of org.apache.log4j.rolling.RFA from extras companion and
         *  org.apache.log4j.RFA from log4j 1.2, respectively). 
         * 
         * */
        class LOG4CXX_EXPORT RollingFileAppenderSkeleton : public FileAppender {
          DECLARE_LOG4CXX_OBJECT(RollingFileAppenderSkeleton)
          BEGIN_LOG4CXX_CAST_MAP()
                  LOG4CXX_CAST_ENTRY(RollingFileAppenderSkeleton)
                  LOG4CXX_CAST_ENTRY_CHAIN(FileAppender)
          END_LOG4CXX_CAST_MAP()

          /**
           * Triggering policy.
           */
          TriggeringPolicyPtr triggeringPolicy;

          /**
           * Rolling policy.
           */
          RollingPolicyPtr rollingPolicy;

          /**
           * Length of current active log file.
           */
          size_t fileLength;

          /**
           *  save the loggingevent
           */
          spi::LoggingEventPtr* _event;
        public:
          /**
           * The default constructor simply calls its {@link
           * FileAppender#FileAppender parents constructor}.
           * */
          RollingFileAppenderSkeleton();

          void activateOptions(log4cxx::helpers::Pool&);


          /**
             Implements the usual roll over behaviour.

             <p>If <code>MaxBackupIndex</code> is positive, then files
             {<code>File.1</code>, ..., <code>File.MaxBackupIndex -1</code>}
             are renamed to {<code>File.2</code>, ...,
             <code>File.MaxBackupIndex</code>}. Moreover, <code>File</code> is
             renamed <code>File.1</code> and closed. A new <code>File</code> is
             created to receive further log output.

             <p>If <code>MaxBackupIndex</code> is equal to zero, then the
             <code>File</code> is truncated with no backup files created.

           */
          bool rollover(log4cxx::helpers::Pool& p);

        protected:

        /**
         Actual writing occurs here.
        */
        virtual void subAppend(const spi::LoggingEventPtr& event, log4cxx::helpers::Pool& p);

        protected:

          RollingPolicyPtr getRollingPolicy() const;

          TriggeringPolicyPtr getTriggeringPolicy() const;

          /**
           * Sets the rolling policy. In case the 'policy' argument also implements
           * {@link TriggeringPolicy}, then the triggering policy for this appender
           * is automatically set to be the policy argument.
           * @param policy
           */
          void setRollingPolicy(const RollingPolicyPtr& policy);

          void setTriggeringPolicy(const TriggeringPolicyPtr& policy);

        public:
          /**
            * Close appender.  Waits for any asynchronous file compression actions to be completed.
          */
          void close();

          protected:
          /**
             Returns an OutputStreamWriter when passed an OutputStream.  The
             encoding used will depend on the value of the
             <code>encoding</code> property.  If the encoding value is
             specified incorrectly the writer will be opened using the default
             system encoding (an error message will be printed to the loglog.
           @param os output stream, may not be null.
           @return new writer.
           */
          log4cxx::helpers::WriterPtr createWriter(log4cxx::helpers::OutputStreamPtr& os);

          public:



          /**
           * Get byte length of current active log file.
           * @return byte length of current active log file.
           */
          size_t getFileLength() const;
          
#ifdef LOG4CXX_MULTI_PROCESS
          /**
           * Set byte length of current active log file.
           * @return void
           */
          void setFileLength(size_t length);

          /**
           *  Release the file lock
           * @return void
           */
          void releaseFileLock(apr_file_t* lock_file);
          /**
           * re-open the latest file when its own handler has been renamed
           * @return void
           */
          void reopenLatestFile(log4cxx::helpers::Pool& p);
#endif

          /**
           * Increments estimated byte length of current active log file.
           * @param increment additional bytes written to log file.
           */
          void incrementFileLength(size_t increment);

        };
        

        LOG4CXX_PTR_DEF(RollingFileAppenderSkeleton);

    }
}

#endif

