/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software License
 * version 1.1, a copy of which has been included with this distribution in
 * the LICENSE file.
 */
package org.apache.log.output.io.rotate;

import java.io.File;
import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.NumberFormat;

import java.io.FilenameFilter;import java.io.FileFilter;/**
 * strategy for naming log files based on appending revolving suffix.
 *
 * @author <a href="mailto:bh22351@i-one.at">Bernhard Huber</a>
 */
public class RevolvingFileStrategy
	implements FileStrategy
{
	///revolving suffix formatting pattern. ie. "'.'000000"
	private final static String      PATTERN = "'.'000000";

	///a revolving suffix formatter
	private DecimalFormat  m_decimalFormat;

	///current revolving suffix
	private int            m_rotation;

	///max revolving value. 
	private int            m_maxRotations;

	///the base file name.
	private File    m_baseFile;

public RevolvingFileStrategy(
  final File baseFile, 
  final int initialRotation, 
  final int maxRotations) {
  m_decimalFormat = new DecimalFormat(PATTERN);

  m_baseFile = baseFile;
  m_rotation = initialRotation;
  m_maxRotations = maxRotations;

  if (-1 == m_maxRotations) {
	m_maxRotations = Integer.MAX_VALUE;
  }

  if (-1 == initialRotation) {
	///TODO: Scan filesystem to get current number

	// First get the path of the base file. Note that this path includes
	// the path and the base of the file name itself.
	String fullFilePathName = m_baseFile.getPath();
	String pathSeparator = System.getProperty("file.separator");
	// Try to find the last path separator (if it exists)
	int fileSeparatorPosition = fullFilePathName.lastIndexOf(pathSeparator);
	File m_basePath;
	
	// If the last path separator does not exist the baseFile is a pure file name
	if (fileSeparatorPosition < 0) {
	  // assume the current directory	
	  m_basePath = new File(".");
	  m_baseFileName = fullFilePathName;
	}
	else {
	  // Extract the sub-directory structure
	  String m_parentPath = fullFilePathName.substring(0, fileSeparatorPosition);
	  m_baseFileName = fullFilePathName.substring(fileSeparatorPosition + 1);
	  m_basePath = new File(m_parentPath);
	}

	File[] matchingFiles = m_basePath.listFiles(new BaseFileNameFilter());

	if (matchingFiles == null)
	  m_rotation = 0;
	else {
	  long oldestFileModificationTime = Long.MAX_VALUE;
	  for (int i = 0; i < matchingFiles.length; i++) {
		String currentFileName = matchingFiles[i].toString();
		//System.out.println(currentFileName + " " + matchingFiles[i].lastModified());
		long fileLastModified = matchingFiles[i].lastModified();
	    // The files may be returned in any order therefore check the rotation number
		int currentFileRotation = Integer.parseInt(currentFileName.substring( currentFileName.length() - m_decimalFormat.getMinimumIntegerDigits()));
		if ((fileLastModified < oldestFileModificationTime) && 
		    (currentFileRotation <= m_maxRotations)) {
		  oldestFileModificationTime = fileLastModified;
		  m_rotation = currentFileRotation;
		}
	  }
	  if (m_rotation == -1)
		m_rotation = 0;
	}
	System.out.println("Starting with file generation " + m_rotation);
  }

  if (m_rotation > m_maxRotations)
	m_rotation = m_maxRotations;
  if (m_rotation < 0)
	m_rotation = 0;
}

	public RevolvingFileStrategy( final File baseFile, final int maxRotations )
	{
		this( baseFile, -1, maxRotations );
	}

	/**
	 * Calculate the real file name from the base filename.
	 *
	 * @return File the calculated file name
	 */
	public File nextFile() 
	{
		final StringBuffer sb = new StringBuffer();
		final FieldPosition fp = new FieldPosition( NumberFormat.INTEGER_FIELD );
		sb.append( m_baseFile );

		final StringBuffer result = m_decimalFormat.format( m_rotation, sb, fp );
		m_rotation += 1;

		if( m_rotation >= m_maxRotations ) m_rotation = 0;

		return new File( result.toString() );
	}
	private String m_baseFileName;private class BaseFileNameFilter implements FilenameFilter {
	public boolean accept(File file, String name) {
		return (name.startsWith(m_baseFileName));
	}	   
}}