/*
 * Copyright (c) 1998, 2020 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.utils.rename;

import java.io.*;
import java.util.*;

/**
 * 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 {
    private static int BUFSIZ = 1024 * 4;

    private List<File> ignoreFiles = new ArrayList<File>();

    private List<RenameValue> renameValues = new ArrayList<RenameValue>();

    private int numberOfTotalFile = 0;

    private int numberOfChangedFile = 0;

    // contains the source-root-directory
    File sourceRootDirFile;

    // contains the destination-root-directory
    File destinationRootDir;

    public PackageRenamer(String sourceFolder, String targetFolder,
            Properties properties) {
        this.sourceRootDirFile = buildAndCheckExistingDirFile(sourceFolder);
        this.destinationRootDir = buildAndCheckDestinationFile(targetFolder);
        initialize(this.sourceRootDirFile, properties);
    }

    public List<File> getIgnoreFiles() {
        return ignoreFiles;
    }

    public List<RenameValue> getRenameValues() {
        return renameValues;
    }

    /**
     * Do a binary copy of the file byte buffer by byte buffer.
     */
    public void binaryCopy(File inFile, File outFile)
            throws FileNotFoundException, IOException {
        byte[] buf = new byte[BUFSIZ];
        FileInputStream in = new FileInputStream(inFile);

        // make sure the directories under this file are available
        String parent = outFile.getParent();
        if (parent != null) {
            File parentFile = new File(parent);
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
        }
        FileOutputStream out = new FileOutputStream(outFile);

        int nBytesRead;
        while ((nBytesRead = in.read(buf)) != -1) {
            out.write(buf, 0, nBytesRead);
        }
        in.close();
        out.close();
    }

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

    public File buildAndCheckDestinationFile(String aDirString) {
        if (aDirString == null) {
            throw new RuntimeException("Invalid destination directory entered.");
        }

        File aDirFile = new File(aDirString);

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

        return aDirFile;
    }

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

        File aDirFile = new File(aDirString);

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

        return aDirFile;
    }

    /**
     * Returns the extension of the given file. Returns and empty string if none
     * was found.
     */
    protected static String parseFileExtension(String fileName) {
        int index = fileName.lastIndexOf('.');
        if (index == -1) {
            return "";
        } else {
            return fileName.substring(index + 1);
        }
    }

    /**
     * Return true if directory2 is contained within directory1. Both
     * directories must be absolute.
     */
    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());
        }
    }

    /**
     * Return true if the PackageRenamer should work on the given file
     * extension.
     */
    public boolean isExtensionSupported(String extension) {
        return extension.equalsIgnoreCase("java")
                || extension.equalsIgnoreCase("xml")
                || extension.equalsIgnoreCase("mwp");
    }

    /**
     * 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() {
        System.out.println("LOG MESSAGES FROM packageRenamer");
        System.out.println("");
        System.out.println("INPUT: -----------------> "
                + sourceRootDirFile.toString());
        System.out.println("OUTPUT: ----------------> "
                + destinationRootDir.toString());

        // Listing the changed file(s)
        System.out.println("List of changed file(s): ");
        traverseSourceDirectory(sourceRootDirFile);

        System.out.println("Total Changed File(s): ------> "
                + numberOfChangedFile);
        System.out.println("Total File(s):         ------> "
                + numberOfTotalFile);
    }

    /**
     * This runSearchAndReplacePackageName() reads an pre-rename source file all
     * into string variable and replacing the old package names with the new
     * ones according to the properties file.
     */
    public void runSearchAndReplacePackageName(File sourceFile) {
        if (getIgnoreFiles().contains(sourceFile)) {
            return;
        }

        String stringContainAllFile = "";
        String sourceFileName = sourceFile.toString();
        String sourceFileNameWithoutRoot = sourceFile.toString().substring(
                sourceRootDirFile.toString().length() + 1);
        String destinationFileNameWithoutRoot = renameFile(sourceFileNameWithoutRoot);

        String destinationFileName = destinationRootDir.toString()
                + File.separator + destinationFileNameWithoutRoot;
        File destFile = new File(destinationFileName);

        if (destFile.exists()) {
            System.out.println("WARNING: Skipping pre-existing: " + destFile);
            return;
        }
        System.out.print("MIGRATING: " + sourceFileName);

        // Reading file into string.
        // stringContainAllFile = readAllStringsFromFile(sourceFileName);
        try {

            FileInputStream fis = new FileInputStream(new File(sourceFileName));
            byte[] buf = new byte[BUFSIZ];
            StringBuffer strBuf = new StringBuffer((int) new 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 RuntimeException(
                    "Unexpected exception was thrown during file manipulation."
                            + ioException.getMessage());
        }

        System.out.print(" -> ");
        // Starting to rename.

        RenameFileData fileData = new RenameFileData(stringContainAllFile,
                false);
        // Make sure package is correct

        String sourcePackageName = null;
        String destPackageName = null;

        if (sourceFileNameWithoutRoot.lastIndexOf('\\') >= 0) {
            sourceFileNameWithoutRoot = sourceFileNameWithoutRoot.substring(0,
                    sourceFileNameWithoutRoot.lastIndexOf('\\'));
            destinationFileNameWithoutRoot = destinationFileNameWithoutRoot
                    .substring(0, destinationFileNameWithoutRoot
                            .lastIndexOf('\\'));
        }
        sourcePackageName = sourceFileNameWithoutRoot.replace('\\', '.');
        destPackageName = destinationFileNameWithoutRoot.replace('\\', '.');
        fileData = new RenameValue("package " + sourcePackageName + ";",
                "package " + destPackageName + ";").replace(fileData);

        for (RenameValue rv : getRenameValues()) {
            fileData = rv.replace(fileData);
        }

        if (fileData.isChanged()) {
            this.numberOfChangedFile++;
        }

        System.out.println(destFile);
        // Writing output file.
        try {

            destFile.getParentFile().mkdirs();

            FileWriter writer = new FileWriter(destFile);
            java.io.PrintWriter out = new java.io.PrintWriter(writer);
            out.print(fileData.getFileContentsString());
            out.close();

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

    public String renameFile(String source) {
        String extension = parseFileExtension(source);
        String resourceName = source.substring(0, source.length()
                - (extension.length() + 1));
        String packageName = resourceName;
        if ("java".equals(extension)) {
            packageName = resourceName.replace('\\', '.');
        }
        String targetPackageName = packageName;

        RenameFileData fileData = new RenameFileData(targetPackageName, true);
        for (RenameValue rv : getRenameValues()) {
            fileData = rv.replace(fileData);
        }

        if ("java".equals(extension)) {
            fileData.setFileContentsString(fileData.getFileContentsString().replace('.', '\\'));
        }

        if (extension != null && extension.length() > 0) {
            fileData.setFileContentsString(fileData.getFileContentsString()
                    + "." + extension);
        }

        return fileData.getFileContentsString();
    }

    /**
     * This traverseSourceDirectory() traverse source-root-directory, creating
     * an corresponding output directory, and calling another method for
     * replacing old TopLink package name.
     */
    public void traverseSourceDirectory(File directory) {
        File[] filesAndDirectories = directory.listFiles();

        for (int i = 0; i < filesAndDirectories.length; i++) {
            File fileOrDirectory = filesAndDirectories[i];

            if (fileOrDirectory.isDirectory()) {
                if (!fileOrDirectory.getName().equalsIgnoreCase(".svn")) {
                    traverseSourceDirectory(fileOrDirectory);
                }
            } else {
                this.numberOfTotalFile++;
                // Check that it does not have an unsupported file extension
                String fileExtension = parseFileExtension(fileOrDirectory
                        .getName());
                if (isExtensionSupported(fileExtension)) {
                    runSearchAndReplacePackageName(fileOrDirectory);
                }
            }
        }
    }

    /**
     *
     * @param srcRoot
     * @param properties
     * @return
     */
    private void initialize(File srcRoot, Properties properties) {
        for (Object key : properties.keySet()) {
            String packageOrClassName = (String) key;
            String value = properties.getProperty(packageOrClassName);

            if (value.equalsIgnoreCase("ignore")) {
                File folder = new File(srcRoot, packageOrClassName.replace('.',
                        '\\'));

                if (folder.exists() && folder.isDirectory()) {
                    addIgnoreFolder(folder, ignoreFiles);
                } else {
                    File file = new File(srcRoot, packageOrClassName.replace(
                            '.', '\\')
                            + ".java");

                    if (file.exists()) {
                        ignoreFiles.add(file);
                    }/*
                         * else { throw new IllegalArgumentException( "Could not
                         * find src to ignore: " + srcRoot + " :: " +
                         * packageOrClassName); }
                         */
                }
            } else {
                renameValues.add(new RenameValue(packageOrClassName, value));
            }
        }
        Collections.sort(renameValues, RenameValue.renameValueComparator());

        /*
         * System.out.println("FILES TO IGNORE"); for (File file : ignoreFiles) {
         * System.out.println("\t> " + file); }
         *
         * System.out.println("\nRENAME VALUES"); for (RenameValue rv :
         * renameValues) { System.out.println("\t" + rv); }
         */
    }

    /**
     *
     * @param folder
     * @param ignoreFiles
     */
    private void addIgnoreFolder(File folder, List<File> ignoreFiles) {
        File[] files = folder.listFiles();

        for (int index = 0; index < files.length; index++) {
            File file = files[index];

            if (file.isFile()
                    && isExtensionSupported(parseFileExtension(file.getName()))) {
                ignoreFiles.add(file);
            } else if (file.isDirectory()
                    && !file.getName().equalsIgnoreCase(".svn")) {
                addIgnoreFolder(file, ignoreFiles);
            }
        }
    }
}
