/*
 * 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.
 */
package org.apache.axis2.deployment.util;

import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * Generates and properly cleans up temporary files. Similar to {@link
 * File#createTempFile(java.lang.String, java.lang.String)}, this class provides a static method to
 * create temporary files. The temporary files will be created in a special directory to be cleaned
 * up the next time this class is loaded by the JVM. This functionality is required because Win32
 * platforms will not allow the JVM to delete files that are open. This causes problems with items
 * such as JARs that get opened by a URLClassLoader and can therefore not be deleted by the JVM
 * (including deleteOnExit).
 * <p/>
 * The caller should not need to create an instance of this class, although it is possible. Simply
 * use the static methods to perform the required operations. Note that all files created by this
 * class should be considered as deleted at JVM exit (although the actual deletion may be delayed).
 * If persistent temporary files are required, use {@link java.io.File} instead.
 * <p/>
 * Refer to Sun bugs 4171239 and 4950148 for more details.
 * <p/>
 * Thanks to Mike Pilone for this code, which was sourced from
 * http://www.devx.com/Java/Article/22018/ and contributed to Apache.
 */

public class TempFileManager {

    /**
     * Creates a temporary file in the proper directory to allow for cleanup after execution. This
     * method delegates to {@link File#createTempFile(java.lang.String, java.lang.String,
     * java.io.File)} so refer to it for more documentation. Any file created using this method should
     * be considered as deleted at JVM exit; therefore, do not use this method to create files that
     * need to be persistent between application runs.
     *
     * @param prefix the prefix string used in generating the file name; must be at least three
     *               characters long
     * @param suffix the suffix string to be used in generating the file's name; may be null, in which
     *               case the suffix ".tmp" will be used
     * @return an abstract pathname denoting a newly created empty file
     * @throws IOException if a file could not be created
     */
    @SuppressWarnings({"ResultOfMethodCallIgnored"})
    public static File createTempFile(String prefix, String suffix)
            throws IOException {
        // Check to see if you have already initialized a temp directory
        // for this class.
        if (sTmpDir == null) {
            // Initialize your temp directory. You use the java temp directory
            // property, so you are sure to find the files on the next run.
            String tmpDirName = System.getProperty("java.io.tmpdir");
            File tmpDir = File.createTempFile(TEMP_DIR_PREFIX, ".tmp",
                                              new File(tmpDirName));

            // Delete the file if one was automatically created by the JVM.
            // You are going to use the name of the file as a directory name,
            // so you do not want the file laying around.
            tmpDir.delete();

            // Create a lock before creating the directory so
            // there is no race condition with another application trying
            // to clean your temp dir.
            File lockFile = new File(tmpDirName, tmpDir.getName() + ".lck");
            lockFile.createNewFile();

            // Set the lock file to delete on exit so it is properly cleaned
            // by the JVM. This will allow the TempFileManager to clean
            // the overall temp directory next time.
            lockFile.deleteOnExit();

            // Make a temp directory that you will use for all future requests.
            if (!tmpDir.mkdirs()) {
                throw new IOException("Unable to create temporary directory:"
                                      + tmpDir.getAbsolutePath());
            }

            sTmpDir = tmpDir;
        }

        // Generate a temp file for the user in your temp directory
        // and return it.
        return File.createTempFile(prefix, suffix, sTmpDir);
    }


    /**
     * Utility method to load the TempFileManager at any time and allow it to clean the temporary
     * files that may be left from previous instances
     *
     * @param args command line arguments are currently not supported
     */
    public static void main(String[] args) {
        // Although the JVM will load the class in order to
        // run the main method, this gives a little clarity to
        // what is happening and why we want the main method.
        try {
            // This will load the TempFileManager, which will
            // cause the static block to execute, cleaning
            // any old temp files.
            Class.forName(TempFileManager.class.getName());
        }
        catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
    }


    /**
     * Deletes all of the files in the given directory, recursing into any sub directories found. Also
     * deletes the root directory.
     *
     * @param rootDir the root directory to be recursively deleted
     * @throws IOException if any file or directory could not be deleted
     */
    private static void recursiveDelete(File rootDir)
            throws IOException {
        // Select all the files
        File[] files = rootDir.listFiles();
        for (File file : files) {
            // If the file is a directory, we will
            // recursively call delete on it.
            if (file.isDirectory()) {
                recursiveDelete(file);
            } else {
                // It is just a file so we are safe to
                // delete it
                if (!file.delete()) {
                    throw new IOException("Could not delete: " + file.getAbsolutePath());
                }
            }
        }

        // Finally, delete the root directory now
        // that all of the files in the directory have
        // been properly deleted.
        if (!rootDir.delete()) {
            throw new IOException("Could not delete: " + rootDir.getAbsolutePath());
        }
    }


    /** The prefix for the temp directory in the system temp directory */
    private final static String TEMP_DIR_PREFIX = "axis2-tmp-";

    /** The temp directory to generate all files in */
    private static File sTmpDir = null;

    /**
     *  Static block used to clean up any old temp directories found -- the JVM
     *  will run this block when a class loader loads the class.
     */
    static {
        // Clean up any old temp directories by listing
        // all of the files, using a filter that will
        // return only directories that start with your
        // prefix.
        FileFilter tmpDirFilter =
                new FileFilter() {
                    public boolean accept(File pathname) {
                        return (pathname.isDirectory() &&
                                pathname.getName().startsWith(TEMP_DIR_PREFIX));
                    }
                };

        // Get the system temp directory and filter the files.
        String tmpDirName = System.getProperty("java.io.tmpdir");
        File tmpDir = new File(tmpDirName);
        File[] tmpFiles = tmpDir.listFiles(tmpDirFilter);

        // Find all the files that do not have a lock by
        // checking if the lock file exists.
        for (File tmpFile : tmpFiles) {
            // Create a file to represent the lock and test.
            File lockFile = new File(tmpFile.getParent(), tmpFile.getName() + ".lck");
            if (!lockFile.exists()) {
                // Delete the contents of the directory since
                // it is no longer locked.
                Logger.getLogger("default").log(Level.FINE,
                                                "TempFileManager::deleting old temp directory " +
                                                tmpFile);

                try {
                    recursiveDelete(tmpFile);
                }
                catch (IOException ex) {
                    // You log at a fine level since not being able to delete
                    // the temp directory should not stop the application
                    // from performing correctly. However, if the application
                    // generates a lot of temp files, this could become
                    // a disk space problem and the level should be raised.
                    Logger.getLogger("default").log(Level.INFO,
                                                    "TempFileManager::unable to delete " +
                                                    tmpFile.getAbsolutePath());

                    // Print the exception.
                    ByteArrayOutputStream ostream = new ByteArrayOutputStream();
                    ex.printStackTrace(new PrintStream(ostream));

                    Logger.getLogger("default").log(Level.FINE, ostream.toString());
                }
            }
        }
    }
}
