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;

/**
 * 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;

	private String m_baseFileName;
	
	private class BaseFileNameFilter implements FilenameFilter {
	public boolean accept(File file, String name) {
		return (name.startsWith(m_baseFileName));
	}	   
}
    public RevolvingFileStrategy( final File baseFile, final int maxRotations )
    {
        this( baseFile, -1, maxRotations );
    }
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) {

      // 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);
      }

      System.out.println("BaseFilePath is " + m_basePath.toString() + " and base file name is " + m_baseFileName);

      File[] matchingFiles = m_basePath.listFiles(new BaseFileNameFilter());

      if (matchingFiles == null) {
         m_rotation = 0;
         System.out.println("No files found! using rotation zero.");

      }
      else {
         long oldestFileModificationTime = Long.MAX_VALUE;
         int earliestRotation = 0;
         int lastRotation = 0;
         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;
               earliestRotation = currentFileRotation;
            }
            if (lastRotation < currentFileRotation)
               lastRotation = currentFileRotation;
         }
         if (lastRotation == m_maxRotations)
            m_rotation = earliestRotation;
         else
            m_rotation = lastRotation + 1;
      }
      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;
}
    /**
     * 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() );
    }
}
