/*
 * 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);

		bool rolloverInternal(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

