/*
 *  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
 *
 *      http://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.ByteArrayOutputStream;
import java.io.File;
import java.io.FilenameFilter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.Locale;

// CheckStyle:LineLengthCheck OFF - urls are long!
/**
 * The Locator is a utility class which is used to find certain items
 * in the environment.
 * <p>
 * It is used at boot time in the launcher, and cannot make use of any of Ant's other classes.
 * <p>
 * This is a surprisingly brittle piece of code, and has had lots of bugs filed against it:
 * <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=42275">running ant off a network share can cause Ant to fail</a>,
 * <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=8031">use File.toURI().toURL().toExternalForm()</a>,
 * <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=42222">Locator implementation not encoding URI strings properly: spaces in paths</a>.
 * It also breaks Eclipse 3.3 Betas:
 * <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=183283">Exception if installation path has spaces</a>.
 * <p>
 * Be very careful when making changes to this class, as a break will upset a lot of people.
 * @since Ant 1.6
 */
// CheckStyle:LineLengthCheck ON - urls are long!
public final class Locator {

    private static final int NIBBLE = 4;
    private static final int NIBBLE_MASK   = 0xF;

    private static final int ASCII_SIZE = 128;

    private static final int BYTE_SIZE = 256;

    private static final int WORD = 16;

    private static final int SPACE = 0x20;
    private static final int DEL = 0x7F;

    // stolen from org.apache.xerces.impl.XMLEntityManager#getUserDir()
    // of the Xerces-J team
    // which ASCII characters need to be escaped
    private static boolean[] gNeedEscaping = new boolean[ASCII_SIZE];
    // the first hex character if a character needs to be escaped
    private static char[] gAfterEscaping1 = new char[ASCII_SIZE];
    // the second hex character if a character needs to be escaped
    private static char[] gAfterEscaping2 = new char[ASCII_SIZE];
    private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
                                     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
    /** Error string used when an invalid uri is seen */
    public static final String ERROR_NOT_FILE_URI
        = "Can only handle valid file: URIs, not ";

    // initialize the above 3 arrays
    static {
        for (int i = 0; i < SPACE; i++) {
            gNeedEscaping[i] = true;
            gAfterEscaping1[i] = gHexChs[i >> NIBBLE];
            gAfterEscaping2[i] = gHexChs[i & NIBBLE_MASK];
        }
        gNeedEscaping[DEL] = true;
        gAfterEscaping1[DEL] = '7';
        gAfterEscaping2[DEL] = 'F';
        char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}',
                         '|', '\\', '^', '~', '[', ']', '`'};
        int len = escChs.length;
        char ch;
        for (int i = 0; i < len; i++) {
            ch = escChs[i];
            gNeedEscaping[ch] = true;
            gAfterEscaping1[ch] = gHexChs[ch >> NIBBLE];
            gAfterEscaping2[ch] = gHexChs[ch & NIBBLE_MASK];
        }
    }
    /**
     * Not instantiable
     */
    private Locator() {
    }

    /**
     * Find the directory or jar file the class has been loaded from.
     *
     * @param c the class whose location is required.
     * @return the file or jar with the class or null if we cannot
     *         determine the location.
     *
     * @since Ant 1.6
     */
    public static File getClassSource(Class<?> c) {
        String classResource = c.getName().replace('.', '/') + ".class";
        return getResourceSource(c.getClassLoader(), classResource);
    }

    /**
     * Find the directory or jar a given resource has been loaded from.
     *
     * @param c the classloader to be consulted for the source.
     * @param resource the resource whose location is required.
     *
     * @return the file with the resource source or null if
     *         we cannot determine the location.
     *
     * @since Ant 1.6
     */
    public static File getResourceSource(ClassLoader c, String resource) {
        if (c == null) {
            c = Locator.class.getClassLoader();
        }
        URL url = null;
        if (c == null) {
            url = ClassLoader.getSystemResource(resource);
        } else {
            url = c.getResource(resource);
        }
        if (url != null) {
            String u = url.toString();
            try {
                if (u.startsWith("jar:file:")) {
                    return new File(fromJarURI(u));
                } else if (u.startsWith("file:")) {
                    int tail = u.indexOf(resource);
                    String dirName = u.substring(0, tail);
                    return new File(fromURI(dirName));
                }
            } catch (IllegalArgumentException e) {
                //unable to determine the URI for reasons unknown.
                return null;
            }
        }
        return null;
    }



    /**
     * Constructs a file path from a <code>file:</code> URI.
     *
     * <p>Will be an absolute path if the given URI is absolute.</p>
     *
     * <p>Prior to Java 1.4,<!-- TODO is JDK version actually relevant? -->
     * swallows '%' that are not followed by two characters.</p>
     *
     * See <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a>
     * which makes some mention of how
     * characters not supported by URI Reference syntax should be escaped.
     *
     * @param uri the URI designating a file in the local filesystem.
     * @return the local file system path for the file.
     * @throws IllegalArgumentException if the URI is malformed or not a legal file: URL
     * @since Ant 1.6
     */
    public static String fromURI(String uri) {
        return fromURIJava13(uri);
        // #buzilla8031: first try Java 1.4.
        // TODO should use java.net.URI now that we can rely on 1.4...
        // but check for UNC-related regressions, e.g. #42275
        // (and remember that \\server\share\file -> file:////server/share/file
        // rather than -> file://server/share/file as it should;
        // fixed only in JDK 7's java.nio.file.Path.toUri)
        // return fromUriJava14(uri);
    }

    /**
     * Java1.4+ code to extract the path from the URI.
     * @param uri
     * @return null if a conversion was not possible
     */
    /* currently unused:
    private static String fromUriJava14(String uri) {
        // Also check for properly formed URIs. Ant formerly recommended using
        // nonsense URIs such as "file:./foo.xml" in XML includes. You shouldn't
        // do that (just "foo.xml" is correct) but for compatibility we special-case
        // things when the path is not absolute, and fall back to the old parsing behavior.
        if (uri.startsWith("file:/")) {
            try {
                File f = new File(URI.create(encodeURI(uri)));
                //bug #42227 forgot to decode before returning
                return decodeUri(f.getAbsolutePath());
            } catch (IllegalArgumentException e) {
                // Bad URI, pass this on.
                // no, this is downgraded to a warning after various
                // JRE bugs surfaced. Hand off
                // to our built in code on a failure
                //throw new IllegalArgumentException(
                //   "Bad URI " + uri + ":" + e.getMessage(), e);
                e.printStackTrace();
            } catch (Exception e) {
                // Unexpected exception? Should not happen.
                e.printStackTrace();
            }
        }
        return null;
    }
     */

    /**
     * @param uri uri to expand
     * @return the decoded URI
     * @since Ant1.7.1
     */
    private static String fromURIJava13(String uri) {
        // Fallback method for Java 1.3 or earlier.

        URL url = null;
        try {
            url = new URL(uri);
        } catch (MalformedURLException emYouEarlEx) {
            // Ignore malformed exception
        }
        if (url == null || !("file".equals(url.getProtocol()))) {
            throw new IllegalArgumentException(ERROR_NOT_FILE_URI + uri);
        }
        StringBuffer buf = new StringBuffer(url.getHost());
        if (buf.length() > 0) {
            buf.insert(0, File.separatorChar).insert(0, File.separatorChar);
        }
        String file = url.getFile();
        int queryPos = file.indexOf('?');
        buf.append((queryPos < 0) ? file : file.substring(0, queryPos));

        uri = buf.toString().replace('/', File.separatorChar);

        if (File.pathSeparatorChar == ';' && uri.startsWith("\\") && uri.length() > 2
            && Character.isLetter(uri.charAt(1)) && uri.lastIndexOf(':') > -1) {
            uri = uri.substring(1);
        }
        String path = null;
        try {
            path = decodeUri(uri);
            //consider adding the current directory. This is not done when
            //the path is a UNC name
            String cwd = System.getProperty("user.dir");
            int posi = cwd.indexOf(':');
            boolean pathStartsWithFileSeparator = path.startsWith(File.separator);
            boolean pathStartsWithUNC = path.startsWith("" + File.separator + File.separator);
            if ((posi > 0) && pathStartsWithFileSeparator && !pathStartsWithUNC) {
                path = cwd.substring(0, posi + 1) + path;
            }
        } catch (UnsupportedEncodingException exc) {
            // not sure whether this is clean, but this method is
            // declared not to throw exceptions.
            throw new IllegalStateException(
                "Could not convert URI " + uri + " to path: "
                + exc.getMessage());
        }
        return path;
    }

    /**
     * Crack a JAR URI.
     * This method is public for testing; we may delete it without any warning -it is not part of Ant's stable API.
     * @param uri uri to expand; contains jar: somewhere in it
     * @return the decoded URI
     * @since Ant1.7.1
     */
    public static String fromJarURI(String uri) {
        int pling = uri.indexOf("!/");
        String jarName = uri.substring("jar:".length(), pling);
        return fromURI(jarName);
    }

    /**
     * Decodes an Uri with % characters.
     * The URI is escaped
     * @param uri String with the uri possibly containing % characters.
     * @return The decoded Uri
     * @throws UnsupportedEncodingException if UTF-8 is not available
     * @since Ant 1.7
     */
    public static String decodeUri(String uri) throws UnsupportedEncodingException {
        if (uri.indexOf('%') == -1) {
            return uri;
        }
        ByteArrayOutputStream sb = new ByteArrayOutputStream(uri.length());
        CharacterIterator iter = new StringCharacterIterator(uri);
        for (char c = iter.first(); c != CharacterIterator.DONE;
             c = iter.next()) {
            if (c == '%') {
                char c1 = iter.next();
                if (c1 != CharacterIterator.DONE) {
                    int i1 = Character.digit(c1, WORD);
                    char c2 = iter.next();
                    if (c2 != CharacterIterator.DONE) {
                        int i2 = Character.digit(c2, WORD);
                        sb.write((char) ((i1 << NIBBLE) + i2));
                    }
                }
            } else if (c >= 0x0000 && c < 0x0080) {
                sb.write(c);
            } else { // #50543
                byte[] bytes = String.valueOf(c).getBytes(StandardCharsets.UTF_8);
                sb.write(bytes, 0, bytes.length);
            }
        }
        return sb.toString(StandardCharsets.UTF_8.name());
    }

    /**
     * Encodes an Uri with % characters.
     * The URI is escaped
     * @param path String to encode.
     * @return The encoded string, according to URI norms
     * @since Ant 1.7
     */
    public static String encodeURI(String path) {
        int i = 0;
        int len = path.length();
        int ch = 0;
        StringBuffer sb = null;
        for (; i < len; i++) {
            ch = path.charAt(i);
            // if it's not an ASCII character, break here, and use UTF-8 encoding
            if (ch >= ASCII_SIZE) {
                break;
            }
            if (gNeedEscaping[ch]) {
                if (sb == null) {
                    sb = new StringBuffer(path.substring(0, i));
                }
                sb.append('%');
                sb.append(gAfterEscaping1[ch]);
                sb.append(gAfterEscaping2[ch]);
                // record the fact that it's escaped
            } else if (sb != null) {
                sb.append((char) ch);
            }
        }

        // we saw some non-ascii character
        if (i < len) {
            if (sb == null) {
                sb = new StringBuffer(path.substring(0, i));
            }
            // get UTF-8 bytes for the remaining sub-string
            byte[] bytes = null;
            byte b;
            bytes = path.substring(i).getBytes(StandardCharsets.UTF_8);
            len = bytes.length;

            // for each byte
            for (i = 0; i < len; i++) {
                b = bytes[i];
                // for non-ascii character: make it positive, then escape
                if (b < 0) {
                    ch = b + BYTE_SIZE;
                    sb.append('%');
                    sb.append(gHexChs[ch >> NIBBLE]);
                    sb.append(gHexChs[ch & NIBBLE_MASK]);
                } else if (gNeedEscaping[b]) {
                    sb.append('%');
                    sb.append(gAfterEscaping1[b]);
                    sb.append(gAfterEscaping2[b]);
                } else {
                    sb.append((char) b);
                }
            }
        }
        return sb == null ? path : sb.toString();
    }

    /**
     * Convert a File to a URL.
     * File.toURL() does not encode characters like #.
     * File.toURI() has been introduced in java 1.4, so
     * Ant cannot use it (except by reflection) <!-- TODO no longer true -->
     * FileUtils.toURI() cannot be used by Locator.java
     * Implemented this way.
     * File.toURL() adds file: and changes '\' to '/' for dos OSes
     * encodeURI converts characters like ' ' and '#' to %DD
     * @param file the file to convert
     * @return URL the converted File
     * @throws MalformedURLException on error
     * @deprecated since 1.9, use {@link FileUtils#getFileURL(File)}
     */
    @Deprecated
    public static URL fileToURL(File file)
        throws MalformedURLException {
        return new URL(file.toURI().toASCIIString());
    }

    /**
     * Get the File necessary to load the Sun compiler tools. If the classes
     * are available to this class, then no additional URL is required and
     * null is returned. This may be because the classes are explicitly in the
     * class path or provided by the JVM directly.
     *
     * @return the tools jar as a File if required, null otherwise.
     */
    public static File getToolsJar() {
        // firstly check if the tools jar is already in the classpath
        boolean toolsJarAvailable = false;
        try {
            // just check whether this throws an exception
            Class.forName("com.sun.tools.javac.Main");
            toolsJarAvailable = true;
        } catch (Exception e) {
            try {
                Class.forName("sun.tools.javac.Main");
                toolsJarAvailable = true;
            } catch (Exception e2) {
                // ignore
            }
        }
        if (toolsJarAvailable) {
            return null;
        }
        // couldn't find compiler - try to find tools.jar
        // based on java.home setting
        String libToolsJar
            = File.separator + "lib" + File.separator + "tools.jar";
        String javaHome = System.getProperty("java.home");
        File toolsJar = new File(javaHome + libToolsJar);
        if (toolsJar.exists()) {
            // Found in java.home as given
            return toolsJar;
        }
        if (javaHome.toLowerCase(Locale.ENGLISH).endsWith(File.separator + "jre")) {
            javaHome = javaHome.substring(
                0, javaHome.length() - "/jre".length());
            toolsJar = new File(javaHome + libToolsJar);
        }
        if (!toolsJar.exists()) {
            System.out.println("Unable to locate tools.jar. "
                 + "Expected to find it in " + toolsJar.getPath());
            return null;
        }
        return toolsJar;
    }

    /**
     * Get an array of URLs representing all of the jar files in the
     * given location. If the location is a file, it is returned as the only
     * element of the array. If the location is a directory, it is scanned for
     * jar files.
     *
     * @param location the location to scan for Jars.
     *
     * @return an array of URLs for all jars in the given location.
     *
     * @exception MalformedURLException if the URLs for the jars cannot be
     *            formed.
     */
    public static URL[] getLocationURLs(File location)
         throws MalformedURLException {
        return getLocationURLs(location, new String[]{".jar"});
    }

    /**
     * Get an array of URLs representing all of the files of a given set of
     * extensions in the given location. If the location is a file, it is
     * returned as the only element of the array. If the location is a
     * directory, it is scanned for matching files.
     *
     * @param location the location to scan for files.
     * @param extensions an array of extension that are to match in the
     *        directory search.
     *
     * @return an array of URLs of matching files.
     * @exception MalformedURLException if the URLs for the files cannot be
     *            formed.
     */
    public static URL[] getLocationURLs(File location,
                                        final String[] extensions)
         throws MalformedURLException {
        URL[] urls = new URL[0];

        if (!location.exists()) {
            return urls;
        }
        if (!location.isDirectory()) {
            urls = new URL[1];
            String path = location.getPath();
            String littlePath = path.toLowerCase(Locale.ENGLISH);
            for (int i = 0; i < extensions.length; ++i) {
                if (littlePath.endsWith(extensions[i])) {
                    urls[0] = fileToURL(location);
                    break;
                }
            }
            return urls;
        }
        File[] matches = location.listFiles(
            new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    String littleName = name.toLowerCase(Locale.ENGLISH);
                    for (int i = 0; i < extensions.length; ++i) {
                        if (littleName.endsWith(extensions[i])) {
                            return true;
                        }
                    }
                    return false;
                }
            });
        urls = new URL[matches.length];
        for (int i = 0; i < matches.length; ++i) {
            urls[i] = fileToURL(matches[i]);
        }
        return urls;
    }
}
