/*
 * 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_FIXED_WINDOW_ROLLING_POLICY_H)
#define _LOG4CXX_ROLLING_FIXED_WINDOW_ROLLING_POLICY_H

#include <log4cxx/rolling/rollingpolicybase.h>




namespace log4cxx
{

namespace helpers
{
class Pool;
}

namespace rolling
{


/**
 * When rolling over, <code>FixedWindowRollingPolicy</code> renames files
 * according to a fixed window algorithm as described below.
 *
 * <p>The <b>ActiveFileName</b> property, which is required, represents the name
 * of the file where current logging output will be written.
 * The <b>FileNamePattern</b>  option represents the file name pattern for the
 * archived (rolled over) log files. If present, the <b>FileNamePattern</b>
 * option must include an integer token, that is the string "%i" somwhere
 * within the pattern.
 *
 * <p>Let <em>max</em> and <em>min</em> represent the values of respectively
 * the <b>MaxIndex</b> and <b>MinIndex</b> options. Let "foo.log" be the value
 * of the <b>ActiveFile</b> option and "foo.%i.log" the value of
 * <b>FileNamePattern</b>. Then, when rolling over, the file
 * <code>foo.<em>max</em>.log</code> will be deleted, the file
 * <code>foo.<em>max-1</em>.log</code> will be renamed as
 * <code>foo.<em>max</em>.log</code>, the file <code>foo.<em>max-2</em>.log</code>
 * renamed as <code>foo.<em>max-1</em>.log</code>, and so on,
 * the file <code>foo.<em>min+1</em>.log</code> renamed as
 * <code>foo.<em>min+2</em>.log</code>. Lastly, the active file <code>foo.log</code>
 * will be renamed as <code>foo.<em>min</em>.log</code> and a new active file name
 * <code>foo.log</code> will be created.
 *
 * <p>Given that this rollover algorithm requires as many file renaming
 * operations as the window size, large window sizes are discouraged. The
 * current implementation will automatically reduce the window size to 12 when
 * larger values are specified by the user.
 *
 *
 *
 *
 * */
class LOG4CXX_EXPORT FixedWindowRollingPolicy : public RollingPolicyBase
{
		DECLARE_LOG4CXX_OBJECT(FixedWindowRollingPolicy)
		BEGIN_LOG4CXX_CAST_MAP()
		LOG4CXX_CAST_ENTRY(FixedWindowRollingPolicy)
		LOG4CXX_CAST_ENTRY_CHAIN(RollingPolicyBase)
		END_LOG4CXX_CAST_MAP()

		int minIndex;
		int maxIndex;
		bool explicitActiveFile;

		/**
		 * It's almost always a bad idea to have a large window size, say over 12.
		 */
		enum { MAX_WINDOW_SIZE = 12 };

		bool purge(int purgeStart, int maxIndex, log4cxx::helpers::Pool& p) const;

	public:

		FixedWindowRollingPolicy();

		void activateOptions(log4cxx::helpers::Pool& p);
		void setOption(const LogString& option,
			const LogString& value);

		void rollover();

		int getMaxIndex() const;

		int getMinIndex() const;

		void setMaxIndex(int newVal);
		void setMinIndex(int newVal);

		/**
		 * {@inheritDoc}
		 */
		RolloverDescriptionPtr initialize(
			const   LogString&              currentActiveFile,
			const   bool                    append,
			log4cxx::helpers::Pool& pool);

		/**
		 * {@inheritDoc}
		 */
		RolloverDescriptionPtr rollover(
			const   LogString&              currentActiveFile,
			const   bool                    append,
			log4cxx::helpers::Pool& pool);

	protected:
		log4cxx::pattern::PatternMap getFormatSpecifiers() const;

};

LOG4CXX_PTR_DEF(FixedWindowRollingPolicy);

}
}

#endif
