/* FileHandler.java -- a class for publishing log messages to log files
   Copyright (C) 2002, 2003, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util.logging;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.LinkedList;
import java.util.ListIterator;

/**
 * A <code>FileHandler</code> publishes log records to a set of log
 * files.  A maximum file size can be specified; as soon as a log file
 * reaches the size limit, it is closed and the next file in the set
 * is taken.
 *
 * <p><strong>Configuration:</strong> Values of the subsequent
 * <code>LogManager</code> properties are taken into consideration
 * when a <code>FileHandler</code> is initialized.  If a property is
 * not defined, or if it has an invalid value, a default is taken
 * without an exception being thrown.
 *
 * <ul>
 *
 * <li><code>java.util.FileHandler.level</code> - specifies
 *     the initial severity level threshold. Default value:
 *     <code>Level.ALL</code>.</li>
 *
 * <li><code>java.util.FileHandler.filter</code> - specifies
 *     the name of a Filter class. Default value: No Filter.</li>
 *
 * <li><code>java.util.FileHandler.formatter</code> - specifies
 *     the name of a Formatter class. Default value:
 *     <code>java.util.logging.XMLFormatter</code>.</li>
 *
 * <li><code>java.util.FileHandler.encoding</code> - specifies
 *     the name of the character encoding. Default value:
 *     the default platform encoding.</li>
 *
 * <li><code>java.util.FileHandler.limit</code> - specifies the number
 *     of bytes a log file is approximately allowed to reach before it
 *     is closed and the handler switches to the next file in the
 *     rotating set.  A value of zero means that files can grow
 *     without limit.  Default value: 0 (unlimited growth).</li>
 *
 * <li><code>java.util.FileHandler.count</code> - specifies the number
 *     of log files through which this handler cycles.  Default value:
 *     1.</li>
 *
 * <li><code>java.util.FileHandler.pattern</code> - specifies a
 *     pattern for the location and name of the produced log files.
 *     See the section on <a href="#filePatterns">file name
 *     patterns</a> for details.  Default value:
 *     <code>"%h/java%u.log"</code>.</li>
 *
 * <li><code>java.util.FileHandler.append</code> - specifies
 *     whether the handler will append log records to existing
 *     files, or whether the handler will clear log files
 *     upon switching to them. Default value: <code>false</code>,
 *     indicating that files will be cleared.</li>
 *
 * </ul>
 *
 * <p><a name="filePatterns"><strong>File Name Patterns:</strong></a>
 * The name and location and log files are specified with pattern
 * strings. The handler will replace the following character sequences
 * when opening log files:
 *
 * <p><ul>
 * <li><code>/</code> - replaced by the platform-specific path name
 *     separator.  This value is taken from the system property
 *     <code>file.separator</code>.</li>
 *
 * <li><code>%t</code> - replaced by the platform-specific location of
 *     the directory intended for temporary files.  This value is
 *     taken from the system property <code>java.io.tmpdir</code>.</li>
 *
 * <li><code>%h</code> - replaced by the location of the home
 *     directory of the current user.  This value is taken from the
 *     system property <code>user.home</code>.</li>
 *
 * <li><code>%g</code> - replaced by a generation number for
 *     distinguisthing the individual items in the rotating set 
 *     of log files.  The generation number cycles through the
 *     sequence 0, 1, ..., <code>count</code> - 1.</li>
 *
 * <li><code>%u</code> - replaced by a unique number for
 *     distinguisthing the output files of several concurrently
 *     running processes.  The <code>FileHandler</code> starts
 *     with 0 when it tries to open a log file.  If the file
 *     cannot be opened because it is currently in use,
 *     the unique number is incremented by one and opening
 *     is tried again.  These steps are repeated until the
 *     opening operation succeeds.
 *
 *     <p>FIXME: Is the following correct? Please review.  The unique
 *     number is determined for each log file individually when it is
 *     opened upon switching to the next file.  Therefore, it is not
 *     correct to assume that all log files in a rotating set bear the
 *     same unique number.
 *
 *     <p>FIXME: The Javadoc for the Sun reference implementation
 *     says: "Note that the use of unique ids to avoid conflicts is
 *     only guaranteed to work reliably when using a local disk file
 *     system." Why? This needs to be mentioned as well, in case
 *     the reviewers decide the statement is true.  Otherwise,
 *     file a bug report with Sun.</li>
 *
 * <li><code>%%</code> - replaced by a single percent sign.</li>
 * </ul>
 *
 * <p>If the pattern string does not contain <code>%g</code> and
 * <code>count</code> is greater than one, the handler will append
 * the string <code>.%g</code> to the specified pattern.
 *
 * <p>If the handler attempts to open a log file, this log file
 * is being used at the time of the attempt, and the pattern string
 * does not contain <code>%u</code>, the handler will append
 * the string <code>.%u</code> to the specified pattern. This
 * step is performed after any generation number has been
 * appended.
 *
 * <p><em>Examples for the GNU platform:</em> 
 *
 * <p><ul>
 *
 * <li><code>%h/java%u.log</code> will lead to a single log file
 *     <code>/home/janet/java0.log</code>, assuming <code>count</code>
 *     equals 1, the user's home directory is
 *     <code>/home/janet</code>, and the attempt to open the file
 *     succeeds.</li>
 *
 * <li><code>%h/java%u.log</code> will lead to three log files
 *     <code>/home/janet/java0.log.0</code>,
 *     <code>/home/janet/java0.log.1</code>, and
 *     <code>/home/janet/java0.log.2</code>,
 *     assuming <code>count</code> equals 3, the user's home
 *     directory is <code>/home/janet</code>, and all attempts
 *     to open files succeed.</li>
 *
 * <li><code>%h/java%u.log</code> will lead to three log files
 *     <code>/home/janet/java0.log.0</code>,
 *     <code>/home/janet/java1.log.1</code>, and
 *     <code>/home/janet/java0.log.2</code>,
 *     assuming <code>count</code> equals 3, the user's home
 *     directory is <code>/home/janet</code>, and the attempt
 *     to open <code>/home/janet/java0.log.1</code> fails.</li>
 *
 * </ul>
 *
 * @author Sascha Brawer (brawer@acm.org)
 */
public class FileHandler
  extends StreamHandler
{
  /**
   * A literal that prefixes all file-handler related properties in the
   * logging.properties file.
   */
  private static final String PROPERTY_PREFIX = "java.util.logging.FileHandler";
  /**
   * The name of the property to set for specifying a file naming (incl. path)
   * pattern to use with rotating log files.
   */
  private static final String PATTERN_KEY = PROPERTY_PREFIX + ".pattern";
  /**
   * The default pattern to use when the <code>PATTERN_KEY</code> property was
   * not specified in the logging.properties file.
   */
  private static final String DEFAULT_PATTERN = "%h/java%u.log";
  /**
   * The name of the property to set for specifying an approximate maximum
   * amount, in bytes, to write to any one log output file. A value of zero
   * (which is the default) implies a no limit.
   */
  private static final String LIMIT_KEY = PROPERTY_PREFIX + ".limit";
  private static final int DEFAULT_LIMIT = 0;
  /**
   * The name of the property to set for specifying how many output files to
   * cycle through. The default value is 1.
   */
  private static final String COUNT_KEY = PROPERTY_PREFIX + ".count";
  private static final int DEFAULT_COUNT = 1;
  /**
   * The name of the property to set for specifying whether this handler should
   * append, or not, its output to existing files. The default value is
   * <code>false</code> meaning NOT to append.
   */
  private static final String APPEND_KEY = PROPERTY_PREFIX + ".append";
  private static final boolean DEFAULT_APPEND = false;

  /**
   * The number of bytes a log file is approximately allowed to reach
   * before it is closed and the handler switches to the next file in
   * the rotating set.  A value of zero means that files can grow
   * without limit.
   */
  private final int limit;


 /**
  * The number of log files through which this handler cycles.
  */
  private final int count;


  /**
   * The pattern for the location and name of the produced log files.
   * See the section on <a href="#filePatterns">file name patterns</a>
   * for details.
   */
  private final String pattern;


  /**
   * Indicates whether the handler will append log records to existing
   * files (<code>true</code>), or whether the handler will clear log files
   * upon switching to them (<code>false</code>).
   */
  private final boolean append;


  /**
   * The number of bytes that have currently been written to the stream.
   * Package private for use in inner classes.
   */
  long written;


  /**
   * A linked list of files we are, or have written to. The entries
   * are file path strings, kept in the order 
   */
  private LinkedList logFiles;


  /**
   * Constructs a <code>FileHandler</code>, taking all property values
   * from the current {@link LogManager LogManager} configuration.
   *
   * @throws java.io.IOException FIXME: The Sun Javadoc says: "if
   *         there are IO problems opening the files."  This conflicts
   *         with the general principle that configuration errors do
   *         not prohibit construction. Needs review.
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure.
   */
  public FileHandler()
    throws IOException, SecurityException
  {
    this(LogManager.getLogManager().getProperty(PATTERN_KEY),
	 LogManager.getIntProperty(LIMIT_KEY, DEFAULT_LIMIT),
	 LogManager.getIntProperty(COUNT_KEY, DEFAULT_COUNT),
	 LogManager.getBooleanProperty(APPEND_KEY, DEFAULT_APPEND));
  }


  /* FIXME: Javadoc missing. */
  public FileHandler(String pattern)
    throws IOException, SecurityException
  {
    this(pattern, DEFAULT_LIMIT, DEFAULT_COUNT, DEFAULT_APPEND);
  }


  /* FIXME: Javadoc missing. */
  public FileHandler(String pattern, boolean append)
    throws IOException, SecurityException
  {
    this(pattern, DEFAULT_LIMIT, DEFAULT_COUNT, append);
  }


  /* FIXME: Javadoc missing. */
  public FileHandler(String pattern, int limit, int count)
    throws IOException, SecurityException
  {
    this(pattern, limit, count, 
	 LogManager.getBooleanProperty(APPEND_KEY, DEFAULT_APPEND));
  }


  /**
   * Constructs a <code>FileHandler</code> given the pattern for the
   * location and name of the produced log files, the size limit, the
   * number of log files thorough which the handler will rotate, and
   * the <code>append</code> property.  All other property values are
   * taken from the current {@link LogManager LogManager}
   * configuration.
   *
   * @param pattern The pattern for the location and name of the
   *        produced log files.  See the section on <a
   *        href="#filePatterns">file name patterns</a> for details.
   *        If <code>pattern</code> is <code>null</code>, the value is
   *        taken from the {@link LogManager LogManager} configuration
   *        property
   *        <code>java.util.logging.FileHandler.pattern</code>.
   *        However, this is a pecularity of the GNU implementation,
   *        and Sun's API specification does not mention what behavior
   *        is to be expected for <code>null</code>. Therefore,
   *        applications should not rely on this feature.
   *
   * @param limit specifies the number of bytes a log file is
   *        approximately allowed to reach before it is closed and the
   *        handler switches to the next file in the rotating set.  A
   *        value of zero means that files can grow without limit.
   *
   * @param count specifies the number of log files through which this
   *        handler cycles.
   *
   * @param append specifies whether the handler will append log
   *        records to existing files (<code>true</code>), or whether the
   *        handler will clear log files upon switching to them
   *        (<code>false</code>).
   *
   * @throws java.io.IOException FIXME: The Sun Javadoc says: "if
   *         there are IO problems opening the files."  This conflicts
   *         with the general principle that configuration errors do
   *         not prohibit construction. Needs review.
   *
   * @throws SecurityException if a security manager exists and
   *         the caller is not granted the permission to control
   *         the logging infrastructure.
   *         <p>FIXME: This seems in contrast to all other handler
   *         constructors -- verify this by running tests against
   *         the Sun reference implementation.
   */
  public FileHandler(String pattern,
		     int limit,
		     int count,
		     boolean append)
    throws IOException, SecurityException
  {
    super(/* output stream, created below */ null,
	  PROPERTY_PREFIX,
	  /* default level */ Level.ALL,
	  /* formatter */ null,
	  /* default formatter */ XMLFormatter.class);

    if ((limit <0) || (count < 1))
      throw new IllegalArgumentException();

    this.pattern = pattern != null ? pattern : DEFAULT_PATTERN;
    this.limit = limit;
    this.count = count;
    this.append = append;
    this.written = 0;
    this.logFiles = new LinkedList ();

    setOutputStream (createFileStream (this.pattern, limit, count, append,
                                       /* generation */ 0));
  }


  /* FIXME: Javadoc missing. */
  private OutputStream createFileStream(String pattern,
                                        int limit,
                                        int count,
                                        boolean append,
                                        int generation)
  {
    String  path;
    int     unique = 0;

    /* Throws a SecurityException if the caller does not have
     * LoggingPermission("control").
     */
    LogManager.getLogManager().checkAccess();

    /* Default value from the java.util.logging.FileHandler.pattern
     * LogManager configuration property.
     */
    if (pattern == null)
      pattern = LogManager.getLogManager().getProperty(PATTERN_KEY);
    if (pattern == null)
      pattern = DEFAULT_PATTERN;

    if (count > 1 && !has (pattern, 'g'))
      pattern = pattern + ".%g";

    do
    {
      path = replaceFileNameEscapes(pattern, generation, unique, count);

      try
      {
	File file = new File(path);
        if (!file.exists () || append)
          {
            FileOutputStream fout = new FileOutputStream (file, append);
            // FIXME we need file locks for this to work properly, but they
            // are not implemented yet in Classpath! Madness!
//             FileChannel channel = fout.getChannel ();
//             FileLock lock = channel.tryLock ();
//             if (lock != null) // We've locked the file.
//               {
                if (logFiles.isEmpty ())
                  logFiles.addFirst (path);
                return new ostr (fout);
//               }
          }
      }
      catch (Exception ex)
      {
        reportError (null, ex, ErrorManager.OPEN_FAILURE);
      }

      unique = unique + 1;
      if (!has (pattern, 'u'))
        pattern = pattern + ".%u";
    }
    while (true);
  }


  /**
   * Replaces the substrings <code>"/"</code> by the value of the
   * system property <code>"file.separator"</code>, <code>"%t"</code>
   * by the value of the system property
   * <code>"java.io.tmpdir"</code>, <code>"%h"</code> by the value of
   * the system property <code>"user.home"</code>, <code>"%g"</code>
   * by the value of <code>generation</code>, <code>"%u"</code> by the
   * value of <code>uniqueNumber</code>, and <code>"%%"</code> by a
   * single percent character.  If <code>pattern</code> does
   * <em>not</em> contain the sequence <code>"%g"</code>,
   * the value of <code>generation</code> will be appended to
   * the result.
   *
   * @throws NullPointerException if one of the system properties
   *         <code>"file.separator"</code>,
   *         <code>"java.io.tmpdir"</code>, or
   *         <code>"user.home"</code> has no value and the
   *         corresponding escape sequence appears in
   *         <code>pattern</code>.
   */
  private static String replaceFileNameEscapes(String pattern,
					       int generation,
					       int uniqueNumber,
					       int count)
  {
    StringBuffer buf = new StringBuffer(pattern);
    String       replaceWith;
    boolean      foundGeneration = false;

    int pos = 0;
    do
    {
      // Uncomment the next line for finding bugs.
      // System.out.println(buf.substring(0,pos) + '|' + buf.substring(pos));
      
      if (buf.charAt(pos) == '/')
      {
	/* The same value is also provided by java.io.File.separator. */
	replaceWith = System.getProperty("file.separator");
	buf.replace(pos, pos + 1, replaceWith);
	pos = pos + replaceWith.length() - 1;
	continue;
      }

      if (buf.charAt(pos) == '%')
      {
        switch (buf.charAt(pos + 1))
	{
	case 't':
	  replaceWith = System.getProperty("java.io.tmpdir");
	  break;

	case 'h':
	  replaceWith = System.getProperty("user.home");
	  break;

	case 'g':
	  replaceWith = Integer.toString(generation);
	  foundGeneration = true;
	  break;

	case 'u':
	  replaceWith = Integer.toString(uniqueNumber);
	  break;

	case '%':
	  replaceWith = "%";
	  break;

	default:
	  replaceWith = "??";
	  break; // FIXME: Throw exception?
	}

	buf.replace(pos, pos + 2, replaceWith);
	pos = pos + replaceWith.length() - 1;
	continue;
      }
    }
    while (++pos < buf.length() - 1);

    if (!foundGeneration && (count > 1))
    {
      buf.append('.');
      buf.append(generation);
    }

    return buf.toString();
  }


  /* FIXME: Javadoc missing. */
  public void publish(LogRecord record)
  {
    if (limit > 0 && written >= limit)
      rotate ();
    super.publish(record);
    flush ();
  }

  /**
   * Rotates the current log files, possibly removing one if we
   * exceed the file count.
   */
  private synchronized void rotate ()
  {
    if (logFiles.size () > 0)
      {
        File f1 = null;
        ListIterator lit = null;

        // If we reach the file count, ditch the oldest file.
        if (logFiles.size () == count)
          {
            f1 = new File ((String) logFiles.getLast ());
            f1.delete ();
            lit = logFiles.listIterator (logFiles.size () - 1);
          }
        // Otherwise, move the oldest to a new location.
        else
          {
            String path = replaceFileNameEscapes (pattern, logFiles.size (),
                                                  /* unique */ 0, count);
            f1 = new File (path);
            logFiles.addLast (path);
            lit = logFiles.listIterator (logFiles.size () - 1);
          }

        // Now rotate the files.
        while (lit.hasPrevious ())
          {
            String s = (String) lit.previous ();
            File f2 = new File (s);
            f2.renameTo (f1);
            f1 = f2;
          }
      }

    setOutputStream (createFileStream (pattern, limit, count, append,
                                       /* generation */ 0));

    // Reset written count.
    written = 0;
  }

  /**
   * Tell if <code>pattern</code> contains the pattern sequence
   * with character <code>escape</code>. That is, if <code>escape</code>
   * is 'g', this method returns true if the given pattern contains
   * "%g", and not just the substring "%g" (for example, in the case of
   * "%%g").
   *
   * @param pattern The pattern to test.
   * @param escape The escape character to search for.
   * @return True iff the pattern contains the escape sequence with the
   *  given character.
   */
  private static boolean has (final String pattern, final char escape)
  {
    final int len = pattern.length ();
    boolean sawPercent = false;
    for (int i = 0; i < len; i++)
      {
        char c = pattern.charAt (i);
        if (sawPercent)
          {
            if (c == escape)
              return true;
            if (c == '%') // Double percent
              {
                sawPercent = false;
                continue;
              }
          }
        sawPercent = (c == '%');
      }
    return false;
  }

  /**
   * An output stream that tracks the number of bytes written to it.
   */
  private final class ostr extends FilterOutputStream
  {
    private ostr (OutputStream out)
    {
      super (out);
    }

    public void write (final int b) throws IOException
    {
      out.write (b);
      FileHandler.this.written++; // FIXME: synchronize?
    }

    public void write (final byte[] b) throws IOException
    {
      write (b, 0, b.length);
    }

    public void write (final byte[] b, final int offset, final int length)
      throws IOException
    {
      out.write (b, offset, length);
      FileHandler.this.written += length; // FIXME: synchronize?
    }
  }
}
