/* ====================================================================
   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.poi.util;

import static org.apache.poi.util.TempFile.JAVA_IO_TMPDIR;

import java.io.File;
import java.io.IOException;
import java.security.SecureRandom;

/**
 * Default implementation of the {@link TempFileCreationStrategy} used by {@link TempFile}:
 * Files are collected into one directory and by default are deleted on exit from the VM.
 * Files may be manually deleted by user prior to JVM exit.
 * Files can be kept by defining the system property {@link #KEEP_FILES}.
 *
 * Each file is registered for deletion with the JVM and the temporary directory is not deleted
 * after the JVM exits. Files that are created in the poifiles directory outside
 * the control of DefaultTempFileCreationStrategy are not deleted.
 * See {@link TempFileCreationStrategy} for better strategies for long-running
 * processes or limited temporary storage.
 */
public class DefaultTempFileCreationStrategy implements TempFileCreationStrategy {
    public static final String POIFILES = "poifiles";

    /** To keep files after JVM exit, set the <code>-Dpoi.keep.tmp.files</code> JVM property */
    public static final String KEEP_FILES = "poi.keep.tmp.files";

    /** random number generator to generate unique filenames */
    private static final SecureRandom random = new SecureRandom();

    /** The directory where the temporary files will be created (<code>null</code> to use the default directory). */
    private File dir;

    /**
     * Creates the strategy so that it creates the temporary files in the default directory.
     *
     * @see File#createTempFile(String, String)
     */
    public DefaultTempFileCreationStrategy() {
        this(null);
    }

    /**
     * Creates the strategy allowing to set the
     *
     * @param dir The directory where the temporary files will be created (<code>null</code> to use the default directory).
     *
     * @see File#createTempFile(String, String, File)
     */
    public DefaultTempFileCreationStrategy(File dir) {
        this.dir = dir;
    }

    private void createPOIFilesDirectory() throws IOException {
        // Identify and create our temp dir, if needed
        // The directory is not deleted, even if it was created by this TempFileCreationStrategy
        if (dir == null) {
            String tmpDir = System.getProperty(JAVA_IO_TMPDIR);
            if (tmpDir == null) {
                throw new IOException("Systems temporary directory not defined - set the -D"+JAVA_IO_TMPDIR+" jvm property!");
            }
            dir = new File(tmpDir, POIFILES);
        }

        createTempDirectory(dir);
    }

    /**
     * Attempt to create a directory, including any necessary parent directories.
     * Does nothing if directory already exists.
     * The method is synchronized to ensure that multiple threads don't try to create the directory at the same time.
     *
     * @param directory  the directory to create
     * @throws IOException if unable to create temporary directory or it is not a directory
     */
    private synchronized void createTempDirectory(File directory) throws IOException {
        // create directory if it doesn't exist
        final boolean dirExists = (directory.exists() || directory.mkdirs());

        if (!dirExists) {
            throw new IOException("Could not create temporary directory '" + directory + "'");
        }
        else if (!directory.isDirectory()) {
            throw new IOException("Could not create temporary directory. '" + directory + "' exists but is not a directory.");
        }
    }

    @Override
    public File createTempFile(String prefix, String suffix) throws IOException {
        // Identify and create our temp dir, if needed
        createPOIFilesDirectory();

        // Generate a unique new filename
        File newFile = File.createTempFile(prefix, suffix, dir);

        // Set the delete on exit flag, unless explicitly disabled
        if (System.getProperty(KEEP_FILES) == null) {
            newFile.deleteOnExit();
        }

        // All done
        return newFile;
    }

    /* (non-JavaDoc) Created directory path is <JAVA_IO_TMPDIR>/poifiles/prefix0123456789 */
    @Override
    public File createTempDirectory(String prefix) throws IOException {
        // Identify and create our temp dir, if needed
        createPOIFilesDirectory();

        // Generate a unique new filename
        // FIXME: Java 7+: use java.nio.Files#createTempDirectory
        final long n = random.nextLong();
        File newDirectory = new File(dir, prefix + Long.toString(n));
        createTempDirectory(newDirectory);

        // Set the delete on exit flag, unless explicitly disabled
        if (System.getProperty(KEEP_FILES) == null) {
            newDirectory.deleteOnExit();
        }

        // All done
        return newDirectory;
    }
}
