/*
 * Copyright (c) 1998, 2019 Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 1998, 2018 IBM Corporation. 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
//     08/29/2016 Jody Grassel
//       - 500441: Eclipselink core has System.getProperty() calls that are not potentially executed under doPriv()
package org.eclipse.persistence.tools;

import org.eclipse.persistence.internal.security.PrivilegedAccessHelper;

import java.io.BufferedReader;
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.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.Objects;
import java.util.Properties;
import java.util.Vector;

/**
 * This class performs package renaming. It demonstrates the following:
 *
 * a) Reading the properties file to be a reference for changing the package
 * name from your source code.
 *
 * b) Traverse source root directory for creating a corresponding output directory
 * and finding the java source file(s) to be changing the package name.
 *
 * c) Search and replace the old TopLink package name(s) with new one(s) according to the reference.
 *
 * You will be able to see the logging message at the command line window
 * where the PackageRenamer is running.
 *
 */
public class PackageRenamer {
    int numberOfTotalFile = 0;
    int numberOfChangedFile = 0;

    // contains the option of Log file.
    boolean specifyLogFile = false;
    java.io.PrintWriter outLog = null;

    // contains the Log File
    String logFileString = null;
    java.io.File logFile;

    // contains the source-root-directory
    java.io.File sourceRootDirFile;

    // contains the destination-root-directory
    java.io.File destinationRootDir;

    // contains the properties file path
    String sourceProperties;

    // contains a reference for renaming
    Properties properties = null;
    String propertiesFileName;
    boolean VERBOSE = true;
    protected static final String SYSTEM_OUT = "System.out";
    BufferedReader reader = null;
    String[] UNSUPPORTED_EXTENSIONS = { "jar", "zip", "ear", "war", "dll", "class", "exe" };
    int BUFSIZ = 1024 * 4;
    final static String CR;

    static {
        // bug 2756643
        CR = PrivilegedAccessHelper.shouldUsePrivilegedAccess() ?
                AccessController.doPrivileged(new PrivilegedAction<String>() {
                    @Override
                    public String run() {
                        return System.getProperty("line.separator");
                    }
                })
                : System.getProperty("line.separator");
    }

    /**
    * The constructor of a PackageRenamer class.
    */
    public PackageRenamer() {
        this(getDefaultPropertiesFileName());
    }

    public PackageRenamer(String propertiesFileName) {
        System.out.println("");
        System.out.println("TopLink Package Renamer");
        System.out.println("-----------------------");
        System.out.println(bannerText());
        sourceRootDirFile = existingDirectoryFromPrompt();
        System.out.println("");
        destinationRootDir = promptForDestinationDirectory();
        System.out.println("");
        this.propertiesFileName = propertiesFileName;
        outLog = streamForNonExistentFilePrompt();
        properties = readChangesFile(propertiesFileName);
    }

    public PackageRenamer(String[] args) {
        this.propertiesFileName = args[0];
        sourceRootDirFile = buildAndCheckExistingDirFile(args[1]);
        destinationRootDir = buildAndCheckDestinationFile(args[2]);
        if (args.length == 4) {
            outLog = buildAndCheckLogWriter(args[3]);
        } else {
            outLog = buildAndCheckLogWriter(SYSTEM_OUT);
        }
        properties = readChangesFile(args[0]);
        logln(bannerText());
    }

    protected String bannerText() {
        StringBuilder stringBuilder = new StringBuilder(CR.length()*3+66+42);
        stringBuilder.append(CR);
        stringBuilder.append("NOTE: The package renamer is meant to be run on plain text files. ");
        stringBuilder.append(CR);
        stringBuilder.append("A rename will NOT be done on binary files.");
        stringBuilder.append(CR);
        return stringBuilder.toString();
    }

    /**
     * Do a binary copy of the file byte buffer by byte buffer.
     *
     * @param inFile
     *            The file to copy
     * @param outFile
     *            The destination file
     * @throws FileNotFoundException
     *             if either of the two files does not exist
     * @throws IOException
     *             if any other IO related error occurs
     */
    public void binaryCopy(File inFile, File outFile) throws FileNotFoundException, IOException {
        byte[] buf = new byte[BUFSIZ];
        try (FileInputStream in = new FileInputStream(inFile);
             FileOutputStream out = new FileOutputStream(outFile)) {
            int nBytesRead;
            while ((nBytesRead = in.read(buf)) != -1) {
                out.write(buf, 0, nBytesRead);
            }
        }
    }

    protected boolean bufferContainsNullChar(byte[] buffer, int bufferLength) {
        for (int i = 0; i < bufferLength; i++) {
            if (buffer[i] == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * INTERNAL Creates a destination directory File object under the path
     * passed, verifying correctness.
     *
     * @param aDirString
     *            The path to the directory File object to create
     * @return The destination directory File object
     */
    public File buildAndCheckDestinationFile(String aDirString) {
        if (aDirString == null) {
            throw new PackageRenamerException("Invalid destination directory entered.");
        }

        File aDirFile = new File(aDirString);

        if (aDirFile.exists()) {
            File[] dirContent = aDirFile.listFiles();
            if (dirContent != null && dirContent.length != 0) {
                throw new PackageRenamerException("Output Directory:" + CR + "  '" + aDirString + "'" + CR + "exists and is not empty.");
            }
        }

        if (!aDirFile.isAbsolute()) {
            throw new PackageRenamerException("A relative destination directory was entered:" + CR + "  '" + aDirString + "'" + CR + "The directory must be absolute.");
        }

        // Check if the destination directory is within the source directory. This would create an infinite loop.
        if (directoryIsSubdirectory(sourceRootDirFile, aDirFile)) {
            throw new PackageRenamerException("Invalid destination directory entered:" + CR + "  '" + aDirString + "'" + CR + "It cannot be a sub-directory of the source directory.");
        }

        return aDirFile;
    }

    public File buildAndCheckExistingDirFile(String aDirString) {
        if (aDirString == null) {
            throw new PackageRenamerException("Invalid source directory entered.");
        }

        File aDirFile = new File(aDirString);

        if (!aDirFile.exists() || !aDirFile.isDirectory()) {
            throw new PackageRenamerException("Input Directory:" + CR + "  '" + aDirString + "'" + CR + "does not exist or is not a directory.");
        }

        if (!aDirFile.isAbsolute()) {
            throw new PackageRenamerException("A relative source directory was entered:" + CR + "  '" + aDirString + "'" + CR + "The directory must be absolute.");
        }

        return aDirFile;
    }

    public PrintWriter buildAndCheckLogWriter(String logFileString) {
        if (logFileString == null) {
            throw new PackageRenamerException("Invalid log file name entered.");
        }

        try {
            if (logFileString.equals(SYSTEM_OUT)) {
                return new PrintWriter(System.out);
            } else {
                File aLogFile = new File(logFileString);

                if (aLogFile.exists()) {
                    throw new PackageRenamerException("Specified log file cannot be created:" + CR + "  '" + logFileString + "'");
                }
                FileWriter writerLog = new FileWriter(logFileString);
                return new java.io.PrintWriter(writerLog);
            }
        } catch (IOException ioException) {
            throw new PackageRenamerException("Unhandled IOException occurred while configuring log file: '" + logFileString + "', " + ioException.getMessage());
        }
    }

    protected void cleanup() {
        //Closing the Log file in case it is being open.
        if (outLog != null) {
            outLog.close();
        }
    }

    /**
     * This method creates an output directory for post-rename file(s).
     *
     * @param aDirectory
     *            The output directory to create
     */
    public void createDestinationDirectory(File aDirectory) {
        if (!aDirectory.exists()) {
            if (!aDirectory.mkdirs()) {
                throw new PackageRenamerException("Error while creating directory:" + CR + "  '" + aDirectory.toString() + "'");
            }
        } else {
            throw new PackageRenamerException("Error directory: '" + aDirectory.toString() + "' already exists but shouldn't.");
        }
    }

    /**
     * Return true if directory2 is contained within directory1. Both
     * directories must be absolute.
     *
     * @param directory1
     *            The higher level directory
     * @param directory2
     *            The lower level directory
     * @return TRUE if directory2 is a subdirectory of directory1
     */
    public static boolean directoryIsSubdirectory(File directory1, File directory2) {
        //        System.out.println(directory1 + " contains " + directory2);
        if (directory2 == null) {
            return false;
        } else if (directory1.equals(directory2)) {
            return true;
        } else {
            return directoryIsSubdirectory(directory1, directory2.getParentFile());
        }
    }

    public File existingDirectoryFromPrompt() {
        System.out.print("Enter the path of the directory which contains the files to rename:" + CR + "> ");
        String aLine = null;
        try {
            aLine = getReader().readLine();
        } catch (IOException exception) {
            throw new PackageRenamerException("Error while reading the source directory: " + exception.getMessage());
        }
        return buildAndCheckExistingDirFile(aLine);
    }

    public static String getDefaultPropertiesFileName() {

        String currentDirectory = PrivilegedAccessHelper.shouldUsePrivilegedAccess() ?
                AccessController.doPrivileged(new PrivilegedAction<String>() {
                    @Override
                    public String run() {
                        return System.getProperty("user.dir");
                    }
                })
                : System.getProperty("user.dir");

        return currentDirectory + File.separator + "packageRename.properties";
    }

    public synchronized BufferedReader getReader() {
        if (reader == null) {
            reader = new BufferedReader(new InputStreamReader(System.in));
        }
        return reader;
    }

    /**
     * Return true if the PackageRenamer should work on the given file
     * extension.
     *
     * @param extension
     *            The file extension to check for being supported
     * @return TRUE if the extension is supported
     */
    public boolean isExtensionSupported(String extension) {
        /* This was cut out because the binary check recognize these files and just copy them byte by byte.
        for (int i=0; i<UNSUPPORTED_EXTENSIONS.length; i++) {
            if ( UNSUPPORTED_EXTENSIONS[i].equalsIgnoreCase(extension)) {
                return false;
            }
        }
        */
        return true;
    }

    /**
     * @param str
     *            The String to log
     */
    public void logln(String str) {
        outLog.println(str);
        outLog.flush();
    }

    /**
     * Main method to run the PackageRenamer
     *
     * @param args
     *            Command line arguments
     */
    public static void main(String[] args) {
        // Check the accuracy of the arguments
        PackageRenamer instance = null;
        try {
            // Creates an instance of an PackageRenamer with some arguments.
            if (args.length == 0) {
                instance = new PackageRenamer();
                instance.run();
            } else if (args.length == 1) {
                instance = new PackageRenamer(args[0]);
                instance.run();
            } else if ((args.length == 3) || (args.length == 4)) {
                instance = new PackageRenamer(args);
                instance.run();
            } else {
                usage();
                System.exit(-1);
            }
        } catch (PackageRenamerException exception) {
            usage();
            System.err.println("**************************************************************************");
            System.err.println("Error during package rename. PACKAGE RENAME FAILED.");
            System.err.println(exception.getMessage());
            System.err.println("**************************************************************************");
            System.exit(-1);
        } catch (Throwable unknowException) {
            System.err.println("Unhandled exception was thrown during rename:");
            unknowException.printStackTrace();
            System.exit(-1);
        }

        instance.logln("");
        instance.logln("PACKAGE RENAME WAS SUCCESSFUL");

        instance.cleanup();

    }

    /**
     * Returns the extension of the given file.
     *
     * @param aFile
     *            The file of which to retrieve the extension
     * @return The file extension or an empty string if none was found.
     */
    public String parseFileExtension(File aFile) {
        int index = aFile.getName().lastIndexOf('.');
        if (index == -1) {
            return "";
        } else {
            return aFile.getName().substring(index + 1);
        }
    }

    /**
     * INTERNAL Prompt from System.in for an empty or non-existent directory to
     * use as the destination directory.
     *
     * @return The destination directory File object
     */
    protected File promptForDestinationDirectory() {
        System.out.print("Enter the path of the directory to which files are to be copied:" + CR + "> ");
        String aLine = null;
        try {
            aLine = getReader().readLine();
        } catch (IOException exception) {
            throw new PackageRenamerException("Error while reading the destination directory specified: " + exception.getMessage());
        }
        return buildAndCheckDestinationFile(aLine);
    }

    /**
     * This readChangesFile() method reads the given properties file to be a
     * reference for renaming TopLink package name.
     *
     * @param filename
     *            The input file to use for the renaming
     * @return The Properties object containing the renaming information
     */
    public Properties readChangesFile(String filename) {
        Properties props = new Properties();
        InputStream in = null;
        try {
            in = new FileInputStream(filename);
            props.load(in);
        } catch (FileNotFoundException fileNotFoundException) {
            throw new PackageRenamerException("Properties file was not found:" + CR + "  '" + filename + "'");
        } catch (IOException ioException) {
            throw new PackageRenamerException("IO error occurred while reading the properties file:'" + filename + "'" + ioException.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                    // ignore
                }
            }
        }
        logln("Using properties file: " + filename);
        return props;
    }

    /**
    * This run() method performs,
    * reading the properties file into properties variable to be a reference for changing package name.
    * creating an destination-root-direetory.
    * and, calling traverseSourceDirectory() method.
    */
    public void run() {
        // Start loging.
        logln("LOG MESSAGES FROM packageRenamer");
        logln("" + new Date());
        logln("");
        logln("INPUT: -----------------> " + sourceRootDirFile.toString());
        logln("OUTPUT: ----------------> " + destinationRootDir.toString());
        //        logln("PROPERTIES FILE: -------> "+sourceProperties);
        //        logln("LOG FILE: --------------> "+writerLog);
        logln("");

        // Root output directory.
        logln("Verifying root output directory...");
        if (!(destinationRootDir.exists())) {
            // Create root directory for output first.
            logln("");
            logln("Creating root output directory...");
            createDestinationDirectory(destinationRootDir);
            logln("");
        }
        logln("Verifying root output directory...DONE");
        logln("");

        // Listing the changed file(s)
        logln("List of changed file(s): ");
        logln("");
        traverseSourceDirectory(sourceRootDirFile);
        logln("");
        logln("Total Changed File(s): ------> " + numberOfChangedFile);
        logln("Total File(s):         ------> " + numberOfTotalFile);
        logln("");

    }

    protected PrintWriter streamForNonExistentFilePrompt() {
        System.out.print("Enter the absolute path of the log file [Hit Enter for SYSTEM.OUT]:" + CR + "> ");
        String aLine = null;
        try {
            aLine = getReader().readLine();
        } catch (IOException exception) {
            throw new PackageRenamerException("Error while reading the name of the log file: " + exception.getMessage());
        }
        if ((aLine != null) && (aLine.length() == 0)) {
            return buildAndCheckLogWriter(SYSTEM_OUT);
        } else {
            return buildAndCheckLogWriter(aLine);
        }
    }

    /**
     * This runSearchAndReplacePackageName() reads a pre-rename source file all
     * into string variable and replacing the old package names with the new
     * ones according to the properties file.
     *
     * @param sourceFile
     *            The source file to process
     */
    public void runSearchAndReplacePackageName(java.io.File sourceFile) {
        String stringContainAllFile = "";
        String sourceFileName = sourceFile.toString();
        String sourceFileNameWithoutRoot = sourceFile.toString().substring(sourceRootDirFile.toString().length() + 1);

        // Rename the file name if required.
        sourceFileNameWithoutRoot = returnNewFileNameIfRequired(sourceFileNameWithoutRoot);

        String destinationFileName = destinationRootDir.toString() + File.separator + sourceFileNameWithoutRoot;

        // Reading file into string.
        // stringContainAllFile = readAllStringsFromFile(sourceFileName);
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(new java.io.File(sourceFileName));
            byte[] buf = new byte[BUFSIZ];
            StringBuffer strBuf = new StringBuffer((int)new java.io.File(sourceFileName).length());
            int i = 0;
            while ((i = fis.read(buf)) != -1) {
                if (bufferContainsNullChar(buf, i)) {
                    // This is a binary file, just copy it byte by byte to the new location. Do not do any renaming.
                    fis.close();
                    binaryCopy(sourceFile, new File(destinationFileName));
                    return;
                }
                String str = new String(buf, 0, i);
                strBuf.append(str);
            }
            fis.close();
            stringContainAllFile = new String(strBuf);

        } catch (IOException ioException) {
            throw new PackageRenamerException("Unexpected exception was thrown during file manipulation." + ioException.getMessage());
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (Exception e) {
                    // ignore
                }
            }
        }

        // Sorting key package name.
        Vector aVector = new Vector();
        for (Enumeration e = properties.keys(); e.hasMoreElements();) {
            aVector.addElement(e.nextElement());
        }
        String[] aStringArrayOfSortedKeyPackageName = new String[aVector.size()];
        aVector.copyInto(aStringArrayOfSortedKeyPackageName);
        Arrays.sort(aStringArrayOfSortedKeyPackageName);

        // Starting to rename.
        boolean alreadyPrint = false;
        int index = aStringArrayOfSortedKeyPackageName.length;
        for (Enumeration enumtr = properties.keys(); enumtr.hasMoreElements();) {
            enumtr.nextElement();
            String key = aStringArrayOfSortedKeyPackageName[index - 1];
            String value = (String)properties.get(key);
            index -= 1;

            // Printing the changed file.
            int found = stringContainAllFile.indexOf(key);
            if ((found != -1) && (!alreadyPrint)) {
                alreadyPrint = true;
                logln((numberOfChangedFile + 1) + ". " + destinationFileName);
                numberOfChangedFile++;
            }

            // replacing the old package name.
            stringContainAllFile = replace(stringContainAllFile, key, value);
        }

        // Writing output file.
        try {
            FileWriter writer = new FileWriter(destinationFileName);
            java.io.PrintWriter out = new java.io.PrintWriter(writer);
            out.print(stringContainAllFile);
            out.close();

        } catch (FileNotFoundException fileNotFoundException) {
            throw new PackageRenamerException("Could not find file to write:" + CR + "  '" + destinationFileName + "'" + CR + fileNotFoundException.getMessage());
        } catch (IOException ioException) {
            throw new PackageRenamerException("Unexpected exception was thrown while writing the file: '" + destinationFileName + "', " + ioException.getMessage());
        }
    }

    /**
     * Do a search and replace in a string.
     *
     * @param str
     *            The original String
     * @param oldChars
     *            The character pattern to replace
     * @param newChars
     *            The character pattern to replace the existing with
     * @return the modified String
     */
    public static String replace(String str, String oldChars, String newChars) {
        int len;
        int pos;
        int lastPos;

        len = newChars.length();
        pos = str.indexOf(oldChars);
        lastPos = pos;

        while (pos > -1) {
            String firstPart;
            String lastPart;

            firstPart = str.substring(0, pos);
            lastPart = str.substring(pos + oldChars.length(), str.length());
            str = firstPart + newChars + lastPart;
            lastPos = pos + len;
            pos = str.indexOf(oldChars, lastPos);
        }

        return (str);
    }

    /**
     * Renames a file based on the properties passed.
     *
     * @param aSourceFileNameWithoutRoot
     *            The original filename
     * @return The new filename, regardless of whether is has been changed
     */
    public String returnNewFileNameIfRequired(String aSourceFileNameWithoutRoot) {
        for (Enumeration enumtr = properties.keys(); enumtr.hasMoreElements();) {
            String key = (String)enumtr.nextElement();

            if (aSourceFileNameWithoutRoot.indexOf(key) != -1) {
                // replacing the old package name.
                aSourceFileNameWithoutRoot = replace(aSourceFileNameWithoutRoot, key, (String)properties.get(key));
            }
        }

        // just simply return whether it has been changed.
        return aSourceFileNameWithoutRoot;
    }

    /**
     * This traverseSourceDirectory() traverse source-root-directory, creating
     * an corresponding output directory, and calling another method for
     * replacing old TopLink package name.
     *
     * @param aDirectoryString
     *            The source root directory to traverse
     */
    public void traverseSourceDirectory(java.io.File aDirectoryString) {
        Objects.requireNonNull(aDirectoryString);
        java.io.File[] filesAndDirectories = aDirectoryString.listFiles();
        if (filesAndDirectories == null) {
            //no content, nothing to work with
            return;
        }
        for (int i = 0; i < filesAndDirectories.length; i++) {
            java.io.File fileOrDirectory = filesAndDirectories[i];
            if (fileOrDirectory.isDirectory()) {
                String sourceDirectoryName = fileOrDirectory.toString();
                String destinationDirectoryName = destinationRootDir.toString() + sourceDirectoryName.substring(sourceRootDirFile.toString().length(), sourceDirectoryName.length());
                createDestinationDirectory(new java.io.File(destinationDirectoryName));
                traverseSourceDirectory(fileOrDirectory);
            } else {
                // it is a file.
                numberOfTotalFile++;
                // Check that it does not have an unsupported file extension
                String fileExtension = parseFileExtension(fileOrDirectory);
                if (isExtensionSupported(fileExtension)) {
                    runSearchAndReplacePackageName(fileOrDirectory);
                }
            }
        }
    }

    public static void usage() {
        System.out.println("");
        System.out.println("TopLink Package Renamer");
        System.out.println("-----------------------");
        System.out.println("");
        System.out.println("The package  renamer should  be run  once on user source code, configuration");
        System.out.println("files,  and   Mapping  Workbench  project  files  that  have  references  to");
        System.out.println("pre-Oracle 9iAS TopLink 9.0.3  API  packages.  The package renamer  works on");
        System.out.println("plain text files and should NOT be run on binary files such as JAR files.");
        System.out.println("");
        System.out.println("The package renamer supports two command line usages. A call which specifies");
        System.out.println("all the required arguments, and  a  call which takes only one parameter.  In");
        System.out.println("this last case, the user is prompted for the missing arguments.");
        System.out.println("");
        System.out.println("Usage:");
        System.out.println("");
        System.out.println("java org.eclipse.persistence.tools.PackageRenamer <properties-file>");
        System.out.println("");
        System.out.println("OR");
        System.out.println("");
        System.out.println("java org.eclipse.persistence.tools.PackageRenamer <properties-file> <source-root-directory> <destination-root-directory> [ <log-file> ]");
        System.out.println("");
        System.out.println("where:");
        System.out.println("\t<properties-file> - File containing  a list of  old and new package");
        System.out.println("\tnames.");
        System.out.println("");
        System.out.println("\t<source-root-directory> - Absolute path name of the directory which");
        System.out.println("\tcontains all the file to be converted.  The <source-root-directory>");
        System.out.println("\twill be searched recursively for files  to convert.  This directory");
        System.out.println("\tshould contain only the plain text files to be converted.");
        System.out.println("");
        System.out.println("\t<destination-root-directory> - Absolute path name of  the directory");
        System.out.println("\twhere the converted directory  structure will be copied.  All files");
        System.out.println("\twill be copied to  the new directory structure whether changes were");
        System.out.println("\tmade or not. This directory must either not exist or be empty.");
        System.out.println("");
        System.out.println("\t<log-file> - The logging  of  the  renaming process will be written");
        System.out.println("\tto the <log-file>.  If no  <log-file>  is  specified  then  logging");
        System.out.println("\twill be written to standard output.");
        System.out.println("");
    }

    // Made static final for performance reasons.
    public static final class PackageRenamerException extends RuntimeException {
        public PackageRenamerException(String aMessage) {
            super(aMessage);
        }
    }
}
