/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.tools.file;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Objects;
import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;

import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.logging.AbstractSessionLog;
import org.eclipse.persistence.logging.SessionLog;

/**
 * INTERNAL:
 *
 * <b>Purpose</b>: Provide common file I/O utilities
 * @author Steven Vo
 * @since TopLink 4.5
 */
public final class FileUtil {

    private FileUtil() {
    }

    /* Copy file to another file or copy content of a directory to another directory
     *
     * @inputPath: path to a file or directory
     * @outputPath: path to a file or directory
     * @filteredExtensions: filter files that end with specified strings i.e {".java", ".class", ".xml"}
     */
    public static void copy(String inputPath, String outputPath, String[] filteredExtensions) throws IOException {
        File inputPathFile = new File(inputPath);

        if (!inputPathFile.exists()) {
            return;
        }

        File outputPathFile = new File(outputPath);

        if (!outputPathFile.exists()) {
            if (outputPathFile.isDirectory()) {
                if (!outputPathFile.mkdirs()) {
                    AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC,
                            "Cannot create directory '{0}'", new Object[] {outputPathFile}, false);
                }
            } else {
                if (!outputPathFile.getParentFile().mkdirs()) {
                    AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC,
                            "Cannot create directory '{0}'", new Object[] {outputPathFile}, false);
                }
            }
        }

        List<File> files = findFiles(inputPath, filteredExtensions);

        for (int i = 0; i < files.size(); i++) {
            File in = files.get(i);

            String outFilePath = in.getAbsolutePath().substring(inputPath.length());
            outFilePath = outputPath + File.separator + outFilePath;

            File out = new File(outFilePath);
            File parent = new File(out.getParent());

            if (!parent.exists()) {
                if (!parent.mkdirs()) {
                    AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC,
                            "Cannot create directory '{0}'", new Object[] {outputPathFile}, false);
                }
            }

            copy(new FileInputStream(in), new FileOutputStream(out));
        }
    }

    /* Copy an input stream to an output stream
     *
     * @in:  input stream
     * @out: output stream
     */
    public static void copy(InputStream in, OutputStream out) throws IOException {
        try (InputStream i = in; OutputStream  o = out) {
            byte[] buffer = new byte[512];
            while (true) {
                int bytesRead = i.read(buffer);
                if (bytesRead == -1) {
                    break;
                }

                o.write(buffer, 0, bytesRead);
            }
        }
    }

    /* Jar a given directory
     *
     * @jarFileName: path of the output jar
     * @jarDirectory: path to the input directory
     * @filteredExtensions: filter files that end with specified strings i.e {".java", ".class", ".xml"}
     */
    public static void createJarFromDirectory(String jarFileName, String jarDirectory, String[] filtertedExtensions) throws IOException {
        File directory = new File(jarDirectory);
        if (!directory.exists()) {
            return;
        }

        File jar = new File(jarFileName);
        if (!jar.exists()) {
            if (!jar.getParentFile().mkdirs()) {
                AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC,
                        "Cannot create directory '{0}'", new Object[] {jar.getParentFile()}, false);
            }
        }
        JarOutputStream jarOut = null;
        try {
            jarOut = new JarOutputStream(new FileOutputStream(jar), new Manifest());
            List<File> files = findFiles(jarDirectory, filtertedExtensions);

            for (int i = 0; i < files.size(); i++) {
                File file = files.get(i);

                String relativePathToDirectory = file.getAbsolutePath().substring(directory.getAbsolutePath().length() + 1);
                String entryName = relativePathToDirectory.replace('\\', '/');

                FileInputStream inStream = null;
                ByteArrayOutputStream byteStream = null;

                try {
                    inStream = new FileInputStream(file);
                    byteStream = new ByteArrayOutputStream();

                    int length = 0;
                    byte[] buffer = new byte[1024];
                    while ((length = inStream.read(buffer)) > 0) {
                        byteStream.write(buffer, 0, length);
                    }
                    byte[] arr = byteStream.toByteArray();

                    JarEntry meta = new JarEntry(entryName);
                    jarOut.putNextEntry(meta);
                    meta.setSize(arr.length);
                    meta.setCompressedSize(arr.length);
                    CRC32 crc = new CRC32();
                    crc.update(arr);
                    meta.setCrc(crc.getValue());
                    meta.setMethod(ZipEntry.STORED);
                    jarOut.write(arr, 0, arr.length);
                    jarOut.closeEntry();
                } finally {
                    Helper.close(byteStream);
                    Helper.close(inStream);
                }
            }
        } finally {
            Helper.close(jarOut);
        }
    }

    /*
     * Return vector of all Files contained in a path.
     *
     * @filteredExtensions: filter files that end with specified strings i.e {".java", ".class", ".xml"}
     *      If filteredExtensions == null or empty then then return all instances of File contained in the directory and its sub directories
     * @Path: a directory path or a file path.
     *      If it's file path then return a single instance of File
     *      If it's directory path then return all instances of File contained in the directory and its sub directories
     */
    public static List<File> findFiles(String path, String[] filteredExtensions) {
        List<File> files = new Vector<>();

        findFilesHelper(new File(path), filteredExtensions, files);
        return files;
    }

    /*
     * INTERNAL: traverse the directory to find all files with filtered extensions.  The result is passed
     * around for each recursive call
     */
    private static void findFilesHelper(File file, String[] filteredExtensions, List<File> result) {
        if (!file.exists()) {
            return;
        }

        if (file.isDirectory()) {
            String[] entries = file.list();

            if (entries != null) {
                for (int i = 0; i < entries.length; i++) {
                    findFilesHelper(new File(file, entries[i]), filteredExtensions, result);
                }
            }
        } else {
            // add everything if no filtered extension
            if ((filteredExtensions == null) || (filteredExtensions.length == 0)) {
                result.add(file);
                return;
            }

            // add only filtered extensions
            for (int i = 0; i < filteredExtensions.length; i++) {
                if (file.getName().endsWith(filteredExtensions[i])) {
                    result.add(file);
                    return;
                }
            }
        }
    }

    /*
     * Delete a file or directory
     *
     * @File: directory or file
     */
    public static void delete(File file) {
        Objects.requireNonNull(file);
        if (!file.exists()) {
            return;
        }

        if (file.isDirectory()) {
            String[] entries = file.list();

            if (entries == null || entries.length == 0) {
                if (!file.delete()) {
                    AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC,
                            "Cannot delete file '{0}'.", new Object[] {file}, false);
                }

            } else {
                for (int i = 0; i < entries.length; i++) {
                    delete(new File(file, entries[i]));
                }

                // delete directory after its containing files were deleted
                String[] content = file.list();
                if (content == null || content.length == 0) {
                    if (!file.delete()) {
                        AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC,
                                "Cannot delete file '{0}'.", new Object[] {file}, false);
                    }
                }
            }
        } else {
            if (!file.delete()) {
                AbstractSessionLog.getLog().log(SessionLog.FINE, SessionLog.MISC,
                        "Cannot delete file '{0}'.", new Object[] {file}, false);
            }
        }
    }
}
