// File.java - File name

/* Copyright (C) 1998, 1999, 2000, 2001  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package java.io;

import java.util.*;
import java.net.*;
import gnu.gcj.runtime.FileDeleter;

/**
 * @author Tom Tromey <tromey@cygnus.com>
 * @date September 24, 1998 
 */

/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * Status:  Complete to version 1.3.
 */

public class File implements Serializable, Comparable
{
  public boolean canRead ()
  {
    checkRead();
    return _access (READ);
  }

  public boolean canWrite ()
  {
    checkWrite();
    return _access (WRITE);
  }
  
  private native boolean performCreate() throws IOException;

  /** @since 1.2 */
  public boolean createNewFile() throws IOException
  {
    checkWrite();
    return performCreate();
  }
  
  private native boolean performDelete ();
  public boolean delete ()
  {
    SecurityManager s = System.getSecurityManager();
    String name = path;
    if (s != null)
      s.checkDelete(path);
    return performDelete ();
  }

  public boolean equals (Object obj)
  {
    if (! (obj instanceof File))
      return false;
    File other = (File) obj;
    if (caseSensitive)
      return (path.equals(other.path));
    else
      return (path.equalsIgnoreCase(other.path));      
  }

  public boolean exists ()
  {
    checkRead();
    return _access (EXISTS);
  }

  public File (String p)
  {
    path = normalizePath(p);
  }

  // Remove duplicate and redundant separator characters.
  private String normalizePath(String p)
  {
    int dupIndex = p.indexOf(dupSeparator);
    int plen = p.length();

    // Special case: permit Windows UNC path prefix.
    if (dupSeparator.equals("\\\\") && dupIndex == 0)
      dupIndex = p.indexOf(dupSeparator, 1);

    if (dupIndex == -1)
      {
        // Ignore trailing separator.
        if (plen > 1 && p.charAt(plen - 1) == separatorChar)
	  return p.substring(0, plen - 1);
	else
	  return p;
      }
    
    StringBuffer newpath = new StringBuffer(plen);
    int last = 0;
    while (dupIndex != -1)
      {
        newpath.append(p.substring(last, dupIndex));
	// Ignore the duplicate path characters.
	while (p.charAt(dupIndex) == separatorChar)
	  {
	    dupIndex++;
	    if (dupIndex == plen)
	      return newpath.toString();
	  }
	newpath.append(separatorChar);
	last = dupIndex;
	dupIndex = p.indexOf(dupSeparator, last);
      }
    
    // Again, ignore possible trailing separator.
    int end;
    if (plen > 1 && p.charAt(plen - 1) == separatorChar)
      end = plen - 1;
    else
      end = plen;
    newpath.append(p.substring(last, end));
    
    return newpath.toString();
  }
  
  public File (String dirPath, String name)
  {
    if (name == null)
      throw new NullPointerException ();
    if (dirPath != null && dirPath.length() > 0)
      {
	// Try to be smart about the number of separator characters.
	if (dirPath.charAt(dirPath.length() - 1) == separatorChar
	    || name.length() == 0)
	  path = normalizePath(dirPath + name);
	else
	  path = normalizePath(dirPath + separatorChar + name);
      }
    else
      path = normalizePath(name);
  }

  public File (File dir, String name)
  {
    this (dir == null ? null : dir.path, name);
  }

  // FIXME  ???
  public String getAbsolutePath ()
  {
    if (isAbsolute ())
      return path;
    return System.getProperty("user.dir") + separatorChar + path;
  }

  /** @since 1.2 */
  public File getAbsoluteFile ()
  {
    return new File (getAbsolutePath());
  }

  public native String getCanonicalPath () throws IOException;

  /** @since 1.2 */
  public File getCanonicalFile () throws IOException
  {
    return new File (getCanonicalPath());
  }

  public String getName ()
  {
    int last = path.lastIndexOf(separatorChar);
    return path.substring(last + 1);
  }

  public String getParent ()
  {
    int last = path.lastIndexOf(separatorChar);
    if (last == -1)
      return null;
    // FIXME: POSIX assumption.
    if (last == 0 && path.charAt (0) == '/')
      ++last;
    return path.substring(0, last);
  }

  /** @since 1.2 */
  public File getParentFile ()
  {
    String parent = getParent ();
    return (parent == null ? null : new File (parent));
  }

  public String getPath ()
  {
    return path;
  }

  public int hashCode ()
  {
    if (caseSensitive)
      return (path.hashCode() ^ 1234321);
    else
      return (path.toLowerCase().hashCode() ^ 1234321);
  }

  public native boolean isAbsolute ();

  public boolean isDirectory ()
  {
    checkRead();
    return _stat (DIRECTORY);
  }

  public boolean isFile ()
  {
    checkRead();
    return _stat (ISFILE);
  }

  /** @since 1.2 */
  public boolean isHidden()
  {
    checkRead();
    return _stat (ISHIDDEN);
  }

  public long lastModified ()
  {
    checkRead();
    return attr (MODIFIED);
  }

  public long length ()
  {
    checkRead();
    return attr (LENGTH);
  }
    
  private final native Object[] performList (FilenameFilter filter,
					     FileFilter fileFilter,
					     Class result_type);

  public String[] list (FilenameFilter filter)
  {
    checkRead();
    return (String[]) performList (filter, null, String.class);
  }

  public String[] list ()
  {
    checkRead();
    return (String[]) performList (null, null, String.class);
  }

  /** @since 1.2 */
  public File[] listFiles()
  {
    checkRead();
    return (File[]) performList (null, null, File.class);
  }
  
  /** @since 1.2 */
  public File[] listFiles(FilenameFilter filter)
  {
    checkRead();
    return (File[]) performList (filter, null, File.class);
  }
  
  /** @since 1.2 */
  public File[] listFiles(FileFilter filter)
  {
    checkRead();
    return (File[]) performList (null, filter, File.class);
  }

  public String toString ()
  {
    return path;
  }

  public URL toURL () throws MalformedURLException
  {
    return new URL ("file://" + getAbsolutePath ()
		    + (isDirectory() ? "/" : ""));
  }

  private final native boolean performMkdir ();

  public boolean mkdir ()
  {
    checkWrite();
    return performMkdir ();
  }

  private static boolean mkdirs (File x)
  {
    if (x.isDirectory())
      return true;
    String p = x.getPath();
    String parent = x.getParent();
    if (parent != null)
      {
	x.path = parent;
	if (! mkdirs (x))
	  return false;
	x.path = p;
      }
    return x.mkdir();
  }

  public boolean mkdirs ()
  {
    checkWrite();
    if (isDirectory ())
      return false;
    return mkdirs (new File (path));
  }

  private static synchronized String nextValue ()
  {
    return Long.toString(counter++, Character.MAX_RADIX);
  }

  /** @since 1.2 */
  public static File createTempFile (String prefix, String suffix,
				     File directory)
    throws IOException
  {
    // Grab the system temp directory if necessary
    if (directory == null)
      {
	String dirname = tmpdir;
	if (dirname == null)
	  throw 
	    new IOException("Cannot determine system temporary directory"); 
	
	directory = new File(dirname);
	if (!directory.exists())
	  throw new IOException("System temporary directory " 
				+ directory.getName() + " does not exist.");
	if (!directory.isDirectory())
	  throw new IOException("System temporary directory " 
				+ directory.getName() 
				+ " is not really a directory.");
      }

    if (prefix.length () < 3)
      throw new IllegalArgumentException ("Prefix too short: " + prefix);
    if (suffix == null)
      suffix = ".tmp";

    // Truncation rules.
    // `6' is the number of characters we generate.
    if (prefix.length () + 6 + suffix.length () > maxPathLen)
      {
	int suf_len = 0;
	if (suffix.charAt(0) == '.')
	  suf_len = 4;
	suffix = suffix.substring(0, suf_len);
	if (prefix.length () + 6 + suf_len > maxPathLen)
	  prefix = prefix.substring(0, maxPathLen - 6 - suf_len);
      }

    File f;

    // How many times should we try?  We choose 100.
    for (int i = 0; i < 100; ++i)
      {
	// This is ugly.
	String t = "ZZZZZZ" + nextValue ();
	String l = prefix + t.substring(t.length() - 6) + suffix;
	try
	  {
	    f = new File(directory, l);
	    if (f.createNewFile())
	      return f;
	  }
	catch (IOException ignored)
	  {
	  }
      }

    throw new IOException ("cannot create temporary file");
  }

  private native boolean performSetReadOnly();

  /** @since 1.2 */
  public boolean setReadOnly()
  {
    checkWrite();
    return performSetReadOnly();
  }

  private static native File[] performListRoots();

  /** @since 1.2 */
  public static File[] listRoots()
  {
    File[] roots = performListRoots();
    
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      {
	// Only return roots to which the security manager permits read access.
	int count = roots.length;
	for (int i = 0; i < roots.length; i++)
	  {
	    try
	      {
        	s.checkRead(roots[i].path);		
	      }
	    catch (SecurityException sx)
	      {
	        roots[i] = null;
		count--;
	      }
	  }
	if (count != roots.length)
	  {
	    File[] newRoots = new File[count];
	    int k = 0;
	    for (int i=0; i < roots.length; i++)
	      {
	        if (roots[i] != null)
		  newRoots[k++] = roots[i];
	      }
	    roots = newRoots;
	  }
      }
    return roots;
  }

  public static File createTempFile (String prefix, String suffix)
    throws IOException
  {
    return createTempFile (prefix, suffix, null);
  }

  /** @since 1.2 */
  public int compareTo(File other)
  {
    if (caseSensitive)
      return path.compareTo (other.path);
    else
      return path.compareToIgnoreCase (other.path);
  }

  /** @since 1.2 */
  public int compareTo(Object o)
  {
    File other = (File) o;
    return compareTo (other);
  }

  private native boolean performRenameTo (File dest);
  public boolean renameTo (File dest)
  {
    SecurityManager s = System.getSecurityManager();
    String sname = getName();
    String dname = dest.getName();
    if (s != null)
      {
	s.checkWrite(sname);
	s.checkWrite(dname);
      }
    return performRenameTo (dest);
  }

  private native boolean performSetLastModified(long time);
  
  /** @since 1.2 */
  public boolean setLastModified(long time)
  {
    checkWrite();
    return performSetLastModified(time);
  }

  public static final String pathSeparator
    = System.getProperty("path.separator");
  public static final char pathSeparatorChar = pathSeparator.charAt(0);
  public static final String separator = System.getProperty("file.separator");
  public static final char separatorChar = separator.charAt(0);

  static final String tmpdir = System.getProperty("java.io.tmpdir");
  static int maxPathLen;
  static boolean caseSensitive;
  static String dupSeparator = separator + separator;
  
  static
  {
    init_native();
  }
  
  // Native function called at class initialization. This should should
  // set the maxPathLen and caseSensitive variables.
  private static native void init_native();

  // The path.
  private String path;

  // We keep a counter for use by createTempFile.  We choose the first
  // value randomly to try to avoid clashes with other VMs.
  private static long counter = Double.doubleToLongBits (Math.random ());

  private void checkWrite ()
  {
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      s.checkWrite(path);
  }

  private void checkRead ()
  {
    SecurityManager s = System.getSecurityManager();
    if (s != null)
      s.checkRead(path);
  }

  /** 
    * Add this File to the set of files to be deleted upon normal
    * termination.
    *
    * @since 1.2 
    */
  // FIXME: This should use the ShutdownHook API once we implement that.
  public void deleteOnExit ()
  {
    SecurityManager sm = System.getSecurityManager ();
    if (sm != null)
      sm.checkDelete (getName ());

    FileDeleter.add (this);
  }

  private void writeObject (ObjectOutputStream oos) throws IOException
  {
    oos.defaultWriteObject ();
    oos.writeChar (separatorChar);
  }

  private void readObject (ObjectInputStream ois)
    throws ClassNotFoundException, IOException
  {
    ois.defaultReadObject ();

    // If the file was from an OS with a different dir separator,
    // fixup the path to use the separator on this OS.
    char oldSeparatorChar = ois.readChar ();
    if (oldSeparatorChar != separatorChar)
      path = path.replace (oldSeparatorChar, separatorChar);
  }

  // QUERY arguments to access function.
  private final static int READ = 0;
  private final static int WRITE = 1;
  private final static int EXISTS = 2;

  // QUERY arguments to stat function.
  private final static int DIRECTORY = 0;
  private final static int ISFILE = 1;
  private final static int ISHIDDEN = 2;

  // QUERY arguments to attr function.
  private final static int MODIFIED = 0;
  private final static int LENGTH = 1;
  
  private final native long attr (int query);
  // On OSF1 V5.0, `stat' is a macro.  It is easiest to use the name
  // `_stat' instead.  We do the same thing for `_access' just in
  // case.
  private final native boolean _access (int query);
  private final native boolean _stat (int query);

  private static final long serialVersionUID = 301077366599181567L;
}
