/*
 * 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.openjpa.lib.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.URL;
import java.net.URLDecoder;
import java.security.AccessController;
import java.security.PrivilegedActionException;

/**
 * Utility operations on files.
 *
 * @author Abe White
 */
public class Files {

    /**
     * Backup the given file to a new file called &lt;file-name&gt;~. If
     * the file does not exist or a backup could not be created, returns null.
     */
    public static File backup(File file, boolean copy) {
        if (file == null || !(AccessController.doPrivileged(
            J2DoPrivHelper.existsAction(file))).booleanValue())
            return null;

        // create new file object copy so we don't modify the original
        String aPath = AccessController.doPrivileged(
            J2DoPrivHelper.getAbsolutePathAction(file));
        File clone = new File(aPath);
        File bk = new File(aPath + "~");
        if (!(AccessController.doPrivileged(
            J2DoPrivHelper.renameToAction(clone, bk))).booleanValue())
            return null;
        if (copy) {
            try {
                copy(bk, file);
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }
        }
        return bk;
    }

    /**
     * Revert the given backup file to the original location. If the given
     * file's name does not end in '~', the '~' is appended before proceeding.
     * If the backup file does not exist or could not be reverted, returns null.
     */
    public static File revert(File backup, boolean copy) {
        if (backup == null)
            return null;
        if (!backup.getName().endsWith("~"))
            backup = new File(backup.getPath() + "~");
        if (!(AccessController.doPrivileged(
            J2DoPrivHelper.existsAction(backup))).booleanValue())
            return null;

        // create new file object copy so we don't modify the original
        String path = AccessController.doPrivileged(
            J2DoPrivHelper.getAbsolutePathAction(backup));
        File clone = new File(path);
        File orig = new File(path.substring(0, path.length() - 1));
        if (!(AccessController.doPrivileged(
            J2DoPrivHelper.renameToAction(clone, orig))).booleanValue())
            return null;
        if (copy) {
            try {
                copy(orig, backup);
            } catch (IOException ioe) {
                throw new RuntimeException(ioe);
            }
        }
        return orig;
    }

    /**
     * Return the source file for the given class, or null if the
     * source is not in the CLASSPATH.
     */
    public static File getSourceFile(Class cls) {
        return getClassFile(cls, ".java");
    }

    /**
     * Return the class file of the given class, or null if the
     * class is in a jar.
     */
    public static File getClassFile(Class cls) {
        return getClassFile(cls, ".class");
    }

    /**
     * Return the file for the class resource with the given extension.
     */
    private static File getClassFile(Class cls, String ext) {
        String name = ClassUtil.getClassName(cls);

        // if it's an inner class, use the parent class name
        int innerIdx = name.indexOf('$');
        if (innerIdx != -1)
            name = name.substring(0, innerIdx);

        URL rsrc = AccessController.doPrivileged(
            J2DoPrivHelper.getResourceAction(cls, name + ext));
        if (rsrc != null && rsrc.getProtocol().equals("file"))
            return new File(URLDecoder.decode(rsrc.getFile()));
        return null;
    }

    /**
     * Return the file for the given package. If the given base directory
     * matches the given package structure, it will be used as-is. If not,
     * the package structure will be added beneath the base directory. If
     * the base directory is null, the current working directory will be
     * used as the base.
     */
    public static File getPackageFile(File base, String pkg, boolean mkdirs) {
        if (base == null)
            base = new File(AccessController.doPrivileged(
                J2DoPrivHelper.getPropertyAction("user.dir")));
        if (StringUtil.isEmpty(pkg)) {
            if (mkdirs && !(AccessController.doPrivileged(
                J2DoPrivHelper.existsAction(base))).booleanValue())
                AccessController.doPrivileged(
                    J2DoPrivHelper.mkdirsAction(base));
            return base;
        }

        pkg = pkg.replace('.', File.separatorChar);
        File file = null;
        try {
            if ((AccessController.doPrivileged(
                J2DoPrivHelper.getCanonicalPathAction(base))).endsWith(pkg))
                file = base;
            else
                file = new File(base, pkg);
        } catch (PrivilegedActionException pae) {
            throw new RuntimeException(
                (IOException) pae.getException());
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }

        if (mkdirs && !(AccessController.doPrivileged(
            J2DoPrivHelper.existsAction(file))).booleanValue())
            AccessController.doPrivileged(J2DoPrivHelper.mkdirsAction(file));
        return file;
    }

    /**
     * Check the given string for a matching file. The string is first
     * tested to see if it is an existing file path. If it does not
     * represent an existing file, it is checked as a resource name of a
     * file. If no resource exists, then it is interpreted as a path
     * to a file that does not exist yet.
     *
     * @param name the file path or resource name
     * @param loader a class loader to use in resource lookup, or null
     * to use the thread's context loader
     */
    public static File getFile(String name, ClassLoader loader) {
        if (name == null)
            return null;

        File file = new File(name);
        if ((AccessController.doPrivileged(
            J2DoPrivHelper.existsAction(file))).booleanValue())
            return file;

        if (loader == null)
            loader = AccessController.doPrivileged(
                J2DoPrivHelper.getContextClassLoaderAction());
        URL url = AccessController.doPrivileged(
            J2DoPrivHelper.getResourceAction(loader, name));
        if (url != null) {
            String urlFile = url.getFile();
            if (urlFile != null) {
                File rsrc = new File(URLDecoder.decode(urlFile));
                if ((AccessController.doPrivileged(
                    J2DoPrivHelper.existsAction(rsrc))).booleanValue())
                    return rsrc;
            }
        }

        // go back to original non-existant file path
        return file;
    }

    /**
     * Return a writer to the stream(stdout or stderr) or file named by the
     * given string.
     *
     * @see #getFile
     */
    public static Writer getWriter(String file, ClassLoader loader)
        throws IOException {
        if (file == null)
            return null;
        if ("stdout".equals(file))
            return new PrintWriter(System.out);
        if ("stderr".equals(file))
            return new PrintWriter(System.err);
        try {
            return new FileWriter(getFile(file, loader));
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }
    }

    /**
     * Return a writer to the stream(stdout or stderr) or file named by the
     * given string set to the provided charset encoding.
     *
     * @see #getOutputStream
     */
    public static Writer getWriter(String file, ClassLoader loader, String enc)
        throws IOException {
        if (file == null)
            return null;
        if (enc == null) {
            // call the non-encoded version of the method
            return getWriter(file, loader);
        }

        try {
            if ("stdout".equals(file))
                return new PrintWriter(new OutputStreamWriter(System.out, enc));
            else if ("stderr".equals(file))
                return new PrintWriter(new OutputStreamWriter(System.err, enc));
            else
                return new BufferedWriter(new OutputStreamWriter(getOutputStream(file, loader), enc));
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }
    }

    /**
     * Return an output stream to the stream(stdout or stderr) or file named
     * by the given string.
     *
     * @see #getFile
     */
    public static OutputStream getOutputStream(String file,
        ClassLoader loader) {
        if (file == null)
            return null;
        if ("stdout".equals(file))
            return System.out;
        if ("stderr".equals(file))
            return System.err;
        try {
            return AccessController.doPrivileged(
                J2DoPrivHelper.newFileOutputStreamAction(
                    getFile(file, loader)));
        } catch (PrivilegedActionException pae) {
            throw new RuntimeException(pae.getException());
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }
    }

    /**
     * Copy a file. Return false if <code>from</code> does not exist.
     */
    public static boolean copy(File from, File to) throws IOException {
        if (from == null || to == null ||
            !(AccessController.doPrivileged(
                J2DoPrivHelper.existsAction(from))).booleanValue())
            return false;

        FileInputStream in = null;
        FileOutputStream out = null;
        try {
            in = AccessController.doPrivileged(
                J2DoPrivHelper.newFileInputStreamAction(from));
            BufferedInputStream inbuf = new BufferedInputStream(in);
            out = AccessController.doPrivileged(
                J2DoPrivHelper.newFileOutputStreamAction(to));
            BufferedOutputStream outbuf = new BufferedOutputStream(out);
            for (int b; (b = inbuf.read()) != -1; outbuf.write(b)) ;
            outbuf.flush();
            return true;
        } catch (PrivilegedActionException pae) {
            throw (FileNotFoundException) pae.getException();
        } finally {
            if (in != null)
                try {
                    in.close();
                } catch (Exception e) {
                }
            if (out != null)
                try {
                    out.close();
                } catch (Exception e) {
                }
        }
    }
}
