/*
 *  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
 *
 *      https://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.tools.ant.launch;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

/**
 * This is a launcher for Ant.
 *
 * @since Ant 1.6
 */
public class Launcher {

    /**
     * The Ant Home (installation) Directory property.
     * {@value}
     */
    public static final String ANTHOME_PROPERTY = "ant.home";

    /**
     * The Ant Library Directory property.
     * {@value}
     */
    public static final String ANTLIBDIR_PROPERTY = "ant.library.dir";

    /**
     * The directory name of the per-user ant directory.
     * {@value}
     */
    public static final String ANT_PRIVATEDIR = ".ant";

    /**
     * The name of a per-user library directory.
     * {@value}
     */
    public static final String ANT_PRIVATELIB = "lib";

    /**
     * The location of a per-user library directory.
     * <p>It's value is the concatenation of {@link #ANT_PRIVATEDIR}
     * with {@link #ANT_PRIVATELIB}, with an appropriate file separator
     * in between. For example, on Unix, it's <code>.ant/lib</code>.</p>
     */
    public static final String USER_LIBDIR =
        ANT_PRIVATEDIR + File.separatorChar + ANT_PRIVATELIB;

    /**
     * The startup class that is to be run.
     * {@value}
     */
    public static final String MAIN_CLASS = "org.apache.tools.ant.Main";

    /**
     * System property with user home directory.
     * {@value}
     */
    public static final String USER_HOMEDIR = "user.home";

    /**
     * System property with application classpath.
     * {@value}
     */
    private static final String JAVA_CLASS_PATH = "java.class.path";

    /**
     * Exit code on trouble
     */
    protected static final int EXIT_CODE_ERROR = 2;

    /**
     * Entry point for starting command line Ant.
     *
     * @param  args commandline arguments
     */
    public static void main(final String[] args) {
        int exitCode;
        boolean launchDiag = false;
        try {
            final Launcher launcher = new Launcher();
            exitCode = launcher.run(args);
            launchDiag = launcher.launchDiag;
        } catch (final LaunchException e) {
            exitCode = EXIT_CODE_ERROR;
            System.err.println(e.getMessage());
        } catch (final Throwable t) {
            exitCode = EXIT_CODE_ERROR;
            t.printStackTrace(System.err); //NOSONAR
        }
        if (exitCode != 0) {
            if (launchDiag) {
                System.out.println("Exit code: " + exitCode);
            }
            System.exit(exitCode);
        }
    }

    /**
     * launch diagnostics flag; for debugging trouble at launch time.
     */
    public boolean launchDiag = false;

    private Launcher() {
    }

    /**
     * Add a CLASSPATH or -lib to lib path urls.
     * Only filesystem resources are supported.
     *
     * @param path        the classpath or lib path to add to the libPathULRLs
     * @param getJars     if true and a path is a directory, add the jars in
     *                    the directory to the path urls
     * @param libPathURLs the list of paths to add to
     * @throws MalformedURLException if we can't create a URL
     */
    private void addPath(final String path, final boolean getJars, final List<URL> libPathURLs)
            throws MalformedURLException {
        final StringTokenizer tokenizer = new StringTokenizer(path, File.pathSeparator);
        while (tokenizer.hasMoreElements()) {
            final String elementName = tokenizer.nextToken();
            final File element = new File(elementName);
            if (elementName.contains("%") && !element.exists()) {
                continue;
            }
            if (getJars && element.isDirectory()) {
                // add any jars in the directory
                for (URL dirURL : Locator.getLocationURLs(element)) {
                    if (launchDiag) {
                        System.out.println("adding library JAR: " + dirURL);
                    }
                    libPathURLs.add(dirURL);
                }
            }

            final URL url = new URL(element.toURI().toASCIIString());
            if (launchDiag) {
                System.out.println("adding library URL: " + url);
            }
            libPathURLs.add(url);
        }
    }

    /**
     * Run the launcher to launch Ant.
     *
     * @param args the command line arguments
     * @return an exit code. As the normal ant main calls exit when it ends,
     *         this is for handling failures at bind-time
     * @throws MalformedURLException if the URLs required for the classloader
     *            cannot be created.
     * @throws LaunchException for launching problems
     */
    private int run(final String[] args)
            throws LaunchException, MalformedURLException {
        final String antHomeProperty = System.getProperty(ANTHOME_PROPERTY);
        File antHome = null;

        final File sourceJar = Locator.getClassSource(getClass());
        final File jarDir = sourceJar.getParentFile();
        String mainClassname = MAIN_CLASS;

        if (antHomeProperty != null) {
            antHome = new File(antHomeProperty);
        }

        if (antHome == null || !antHome.exists()) {
            antHome = jarDir.getParentFile();
            setProperty(ANTHOME_PROPERTY, antHome.getAbsolutePath());
        }

        if (!antHome.exists()) {
            throw new LaunchException(
                "Ant home is set incorrectly or ant could not be located (estimated value="
                    + antHome.getAbsolutePath() + ")");
        }

        final List<String> libPaths = new ArrayList<>();
        String cpString = null;
        final List<String> argList = new ArrayList<>();
        String[] newArgs;
        boolean  noUserLib = false;
        boolean  noClassPath = false;

        for (int i = 0; i < args.length; ++i) {
            if ("-lib".equals(args[i])) {
                if (i == args.length - 1) {
                    throw new LaunchException(
                        "The -lib argument must be followed by a library location");
                }
                libPaths.add(args[++i]);
            } else if ("-cp".equals(args[i])) {
                if (i == args.length - 1) {
                    throw new LaunchException(
                        "The -cp argument must be followed by a classpath expression");
                }
                if (cpString != null) {
                    throw new LaunchException(
                        "The -cp argument must not be repeated");
                }
                cpString = args[++i];
            } else if ("--nouserlib".equals(args[i]) || "-nouserlib".equals(args[i])) {
                noUserLib = true;
            } else if ("--launchdiag".equals(args[i])) {
                launchDiag = true;
            } else if ("--noclasspath".equals(args[i]) || "-noclasspath".equals(args[i])) {
                noClassPath = true;
            } else if ("-main".equals(args[i])) {
                if (i == args.length - 1) {
                    throw new LaunchException(
                        "The -main argument must be followed by a library location");
                }
                mainClassname = args[++i];
            } else {
                argList.add(args[i]);
            }
        }

        logPath("Launcher JAR", sourceJar);
        logPath("Launcher JAR directory", sourceJar.getParentFile());
        logPath("java.home", new File(System.getProperty("java.home")));

        //decide whether to copy the existing arg set, or
        //build a new one from the list of all args excluding the special
        //operations that only we handle
        if (argList.size() == args.length) {
            newArgs = args;
        } else {
            newArgs = argList.toArray(new String[argList.size()]);
        }

        final URL[] libURLs    = getLibPathURLs(
            noClassPath ? null : cpString, libPaths);
        final URL[] systemURLs = getSystemURLs(jarDir);
        final URL[] userURLs   = noUserLib ? new URL[0] : getUserURLs();

        final File toolsJAR = Locator.getToolsJar();
        logPath("tools.jar", toolsJAR);
        final URL[] jars = getJarArray(
            libURLs, userURLs, systemURLs, toolsJAR);

        // now update the class.path property
        final StringBuilder baseClassPath
            = new StringBuilder(System.getProperty(JAVA_CLASS_PATH));
        if (baseClassPath.charAt(baseClassPath.length() - 1)
                == File.pathSeparatorChar) {
            baseClassPath.setLength(baseClassPath.length() - 1);
        }

        for (URL jar : jars) {
            baseClassPath.append(File.pathSeparatorChar);
            baseClassPath.append(Locator.fromURI(jar.toString()));
        }

        setProperty(JAVA_CLASS_PATH, baseClassPath.toString());

        final URLClassLoader loader = new URLClassLoader(jars, Launcher.class.getClassLoader());
        Thread.currentThread().setContextClassLoader(loader);
        Class<? extends AntMain> mainClass = null;
        int exitCode = 0;
        Throwable thrown = null;
        try {
            mainClass = loader.loadClass(mainClassname).asSubclass(AntMain.class);
            final AntMain main = mainClass.getDeclaredConstructor().newInstance();
            main.startAnt(newArgs, null, null);
        } catch (final InstantiationException ex) {
            System.err.println(
                "Incompatible version of " + mainClassname + " detected");
            final File mainJar = Locator.getClassSource(mainClass);
            System.err.println(
                "Location of this class " + mainJar);
            thrown = ex;
        } catch (final ClassNotFoundException cnfe) {
            System.err.println(
                    "Failed to locate" + mainClassname);
            thrown = cnfe;
        } catch (final Throwable t) {
            t.printStackTrace(System.err); //NOSONAR
            thrown = t;
        }
        if (thrown != null) {
            System.err.println(ANTHOME_PROPERTY + ": " + antHome.getAbsolutePath());
            System.err.println("Classpath: " + baseClassPath.toString());
            System.err.println("Launcher JAR: " + sourceJar.getAbsolutePath());
            System.err.println("Launcher Directory: " + jarDir.getAbsolutePath());
            exitCode = EXIT_CODE_ERROR;
        }
        return exitCode;
    }

    /**
     * Get the list of -lib entries and -cp entry into
     * a URL array.
     * @param cpString the classpath string
     * @param libPaths the list of -lib entries.
     * @return an array of URLs.
     * @throws MalformedURLException if the URLs  cannot be created.
     */
    private URL[] getLibPathURLs(final String cpString, final List<String> libPaths)
        throws MalformedURLException {
        final List<URL> libPathURLs = new ArrayList<>();

        if (cpString != null) {
            addPath(cpString, false, libPathURLs);
        }

        for (final String libPath : libPaths) {
            addPath(libPath, true, libPathURLs);
        }

        return libPathURLs.toArray(new URL[libPathURLs.size()]);
    }

    /**
     * Get the jar files in ANT_HOME/lib.
     * determine ant library directory for system jars: use property
     * or default using location of ant-launcher.jar
     * @param antLauncherDir the dir that ant-launcher ran from
     * @return the URLs
     * @throws MalformedURLException if the URLs cannot be created.
     */
    private URL[] getSystemURLs(final File antLauncherDir) throws MalformedURLException {
        File antLibDir = null;
        final String antLibDirProperty = System.getProperty(ANTLIBDIR_PROPERTY);
        if (antLibDirProperty != null) {
            antLibDir = new File(antLibDirProperty);
        }
        if (antLibDir == null || !antLibDir.exists()) {
            antLibDir = antLauncherDir;
            setProperty(ANTLIBDIR_PROPERTY, antLibDir.getAbsolutePath());
        }
        return Locator.getLocationURLs(antLibDir);
    }

    /**
     * Get the jar files in user.home/.ant/lib
     * @return the URLS from the user's lib dir
     * @throws MalformedURLException if the URLs cannot be created.
     */
    private URL[] getUserURLs() throws MalformedURLException {
        final File userLibDir
            = new File(System.getProperty(USER_HOMEDIR), USER_LIBDIR);

        return Locator.getLocationURLs(userLibDir);
    }

    /**
     * Combine the various jar sources into a single array of jars.
     * @param libJars the jars specified in -lib command line options
     * @param userJars the jars in ~/.ant/lib
     * @param systemJars the jars in $ANT_HOME/lib
     * @param toolsJar   the tools.jar file
     * @return a combined array
     * @throws MalformedURLException if there is a problem.
     */
    private URL[] getJarArray(final URL[] libJars, final URL[] userJars,
        final URL[] systemJars, final File toolsJar)
        throws MalformedURLException {
        int numJars = libJars.length + userJars.length + systemJars.length;
        if (toolsJar != null) {
            numJars++;
        }
        final URL[] jars = new URL[numJars];
        System.arraycopy(libJars, 0, jars, 0, libJars.length);
        System.arraycopy(userJars, 0, jars, libJars.length, userJars.length);
        System.arraycopy(systemJars, 0, jars, userJars.length + libJars.length,
            systemJars.length);

        if (toolsJar != null) {
            jars[jars.length - 1] = new URL(toolsJar.toURI().toASCIIString());
        }
        return jars;
    }

    /**
     * set a system property, optionally log what is going on
     * @param name property name
     * @param value value
     */
    private void setProperty(final String name, final String value) {
        if (launchDiag) {
            System.out.println("Setting \"" + name + "\" to \"" + value + "\"");
        }
        System.setProperty(name, value);
    }

    private void logPath(final String name, final File path) {
        if (launchDiag) {
            System.out.println(name + "= \"" + path + "\"");
        }
    }
}
