/*
 * Copyright (c) 1998, 2021 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<Object> aVector = new Vector<>();
        for (Enumeration<Object> 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<Object> 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<Object> 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);
        }
    }
}
