/**
 * 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.netbeans.modules.web.common.api;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.netbeans.api.editor.mimelookup.MimePath;
import org.netbeans.api.project.Project;
import org.netbeans.modules.parsing.api.Embedding;
import org.netbeans.modules.parsing.api.ResultIterator;
import org.netbeans.modules.web.common.spi.ProjectWebRootProvider;
import org.netbeans.modules.web.common.spi.ProjectWebRootQuery;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
import org.openide.util.Parameters;

/**
 * Various web utilities
 *
 * @author marekfukala
 */
public class WebUtils {

    private static final Logger LOGGER = Logger.getLogger(WebUtils.class.getName());
    static boolean UNIT_TESTING = false;
    static FileObject WEB_ROOT;

    /**
     * Resolves the relative or absolute link from the base file
     *
     * @param source The base file
     * @param importedFileName the link
     * @return
     */
    public static FileObject resolve(FileObject source, String importedFileName) {
        FileReference ref = resolveToReference(source, importedFileName);
        return ref == null ? null : ref.target();
    }

    /**
     * Resolves the relative or absolute link from the base file
     *
     * @param source The base file
     * @param importedFileName the file link
     * @return FileReference instance which is a reference descriptor
     */
    public static FileReference resolveToReference(FileObject source, String importedFileName) {
        Parameters.notNull("source", source);
        Parameters.notNull("importedFileName", importedFileName);

        //possibly remove the query part of the link
        int qmIndex = importedFileName.indexOf("?"); //NOI18N
        if (qmIndex >= 0) {
            importedFileName = importedFileName.substring(0, qmIndex);
        }
        //possibly remove the fragment part of the link
        int fragmentIndex  = importedFileName.indexOf("#");
        if (fragmentIndex >= 0) {
            importedFileName = importedFileName.substring(0, fragmentIndex);
        }
        
        try {
            URI u = new URI(importedFileName);
            File file = null;

            //does the uri have a scheme component?
            if (u.isAbsolute()) {
                //do refactor only file resources
                if ("file".equals(u.getScheme())) { //NOI18N
                    try {
                        //the IAE is thrown for invalid URIs quite frequently
                        file = new File(u);
                    } catch (IllegalArgumentException iae) {
                        //no-op
                    }
                }
            } else {
                //no schema specified
                file = new File(importedFileName);
            }

            if (file != null) {
                if (!isAbsolute(file, importedFileName)) {
                    //relative to the current file's folder - let's resolve
                    FileObject parent = source.getParent();
                    if(parent != null) {
                        FileObject resolvedFileObject = parent.getFileObject(URLDecoder.decode(importedFileName, "UTF-8")); //NOI18N
                        //test if the link is resolved to something else than the parent file,
                        //which may happen at least in the case of empty importedFileName string
                        if (resolvedFileObject != null &&
                                resolvedFileObject.isValid() &&
                                !resolvedFileObject.equals(parent)) {
                            //normalize the file (may contain xxx/../../yyy parts which
                            //causes that fileobject representing the same file are not equal
                            File resolvedFile = FileUtil.toFile(resolvedFileObject);
                            if(resolvedFile != null) {
                                FileObject resolvedFileObjectInCanonicalForm = FileUtil.toFileObject(resolvedFile);
                                //find out the base folder - bottom most folder of the link
                                FileObject linkBase = findRelativeLinkBase(source, importedFileName);
                                FileReference ref = new FileReference(source, resolvedFileObjectInCanonicalForm, linkBase, importedFileName, FileReferenceType.RELATIVE);
                                return ref;
                            }
                        }
                    }
                } else {
                    //absolute web path
                    FileObject webRoot = ProjectWebRootQuery.getWebRoot(source); //find web root
                    if(UNIT_TESTING) {
                        webRoot = WEB_ROOT;
                    }
                    if(webRoot != null) {
                        //resolve the link relative to the web root
                        String path = file.getAbsolutePath();
                        if (path.length() > webRoot.getPath().length() && webRoot.getPath().equals(path.substring(0, webRoot.getPath().length()))) {
                            path = path.substring(webRoot.getPath().length());
                        }
                        FileObject resolved = webRoot.getFileObject(path);
                        if (resolved != null && resolved.isValid()) {
                            FileReference ref = new FileReference(source, resolved, webRoot, importedFileName, FileReferenceType.ABSOLUTE);
                            return ref;
                        }
                    }
                }
            }

        } catch (URISyntaxException ex) {
            //simply a bad link, return null, no need to report the exception
        } catch (IOException e) {
            Logger.getAnonymousLogger().log(Level.INFO, "Cannot resolve import '" + importedFileName + "' from file " + source.getPath(), e); //NOI18N
        }
        return null;
    }

    //windows File.isAbsolute() workaround
    private static boolean isAbsolute(File file, String link) {
        if(file.isAbsolute()) {
            return true; //will not be true on windows
        } else {
            return link.startsWith("/"); //NOI18N
        }
    }

    private static FileObject findRelativeLinkBase(FileObject source, String link) {
        //Example:
        //
        //  root
        //   +---A
        //       +---file0
        //       +---B
        //           +---C
        //           |   +---file1
        //           |
        //           +---D
        //               +---file2
        //
        //If there is a link ../C/file1 in file2 the bottom most folder is B
        //If there is a link ../../file0 in file2 the bottom most folder is A
        //If there is a link B/C/file1 in file0 the bottom most folder is A
        assert !source.isFolder() : "The source file " + source.getPath() + " is not a folder!"; //NOI18N
        assert !link.startsWith("/") : "The relative link " + link + "starts with a slash!"; //NOI18N
        if(link.startsWith("./")) { //NOI18N
            link = link.substring(2); //cut off the ./
        }
        StringTokenizer st = new StringTokenizer(link, "/");
        FileObject base = source.getParent();
        while(st.hasMoreTokens()) {
            String part = st.nextToken();
            if(part.equals("..")) {
                base = base.getParent();
                if(base == null) {
                    //cannot resolve
                    break;
                }
            } else {
                //we are in the ascending path part, return the current base folder
                return base;
            }
        }
        return null;

    }

    private static int getMimePathSize(ResultIterator ri) {
        return ri.getSnapshot().getMimePath().size();
    }

    /** Finds ResultIterator of the given mimetype with the shortest {@link MimePath}. */
    public static ResultIterator getResultIterator(ResultIterator ri, String mimetype) {
        if (ri.getSnapshot().getMimeType().equals(mimetype)) {
            return ri;
        }

        List<ResultIterator>resultIterators = new ArrayList<ResultIterator>();
        for (Embedding e : ri.getEmbeddings()) {
            ResultIterator eri = ri.getResultIterator(e);
            if (e.getMimeType().equals(mimetype)) {
                // not returned immediately to be able detect mimePaths with equal size
                resultIterators.add(eri);
            } else {
                ResultIterator eeri = getResultIterator(eri, mimetype);
                if (eeri != null) {
                    resultIterators.add(eeri);
                }
            }
        }

        // choses the one with the shortest MimePath
        ResultIterator shortestMimePathRI = null;
        for (ResultIterator resultIterator : resultIterators) {
            if (shortestMimePathRI == null || getMimePathSize(resultIterator) < getMimePathSize(shortestMimePathRI)) {
                shortestMimePathRI = resultIterator;
            } else if (getMimePathSize(resultIterator) == getMimePathSize(shortestMimePathRI)) {
                LOGGER.log(Level.INFO, "Equally long MimePaths for MimeType={0} found: {1}; {2}", new Object[]{
                    mimetype,
                    shortestMimePathRI.getSnapshot().getMimePath().getPath(),
                    resultIterator.getSnapshot().getMimePath().getPath()});
            }
        }
        return shortestMimePathRI;
    }

    public static String unquotedValue(CharSequence value) {
        CharSequence unquoted = isValueQuoted(value) ? value.subSequence(1, value.length() - 1) : value;
        return unquoted.toString();
    }

    public static boolean isValueQuoted(CharSequence value) {
        if (value.length() < 2) {
            return false;
        } else {
            return ((value.charAt(0) == '\'' || value.charAt(0) == '"')
                    && (value.charAt(value.length() - 1) == '\'' || value.charAt(value.length() - 1) == '"'));
        }
    }

    /**
     * Returns a relative path from source to target in one web-like project.
     * ProjectWebRootQuery must return the same folder for both arguments.
     *
     * @param source normalized FileObject in canonical form
     * @param target normalized FileObject in canonical form
     * @return
     */
    public static String getRelativePath(FileObject source, FileObject target) {
        if(!source.isData()) {
            throw new IllegalArgumentException("The source file " + source.getPath() + " is not a data file!");
        }
        if(!target.isData()) {
            throw new IllegalArgumentException("The target file " + target.getPath() + " is not a data file!");
        }

        //link: ../../folder/file.txt
        List<FileObject> targetPathFiles = new ArrayList<FileObject>();
        FileObject file = target;
        while ((file = file.getParent()) != null) {
            assert file.isFolder();
            targetPathFiles.add(0, file);
        }

        //now iterate the target parent's until we find a common folder
        FileObject common = null;
        file = source;
        StringBuilder link = new StringBuilder();
        while ((file = file.getParent()) != null) {
            if (targetPathFiles.contains(file)) {
                common = file;
                break;
            } else {
                link.append("../");//NOI18N
            }
        }
        if (common == null) {
            //no common ancestor
            return null;
        }

        int commonIndexInSourcePath = targetPathFiles.indexOf(common);
        assert commonIndexInSourcePath >= 0;
        assert targetPathFiles.size() > commonIndexInSourcePath;

        for (int i = commonIndexInSourcePath + 1; i < targetPathFiles.size(); i++) {
            FileObject pathMember = targetPathFiles.get(i);
            link.append(pathMember.getNameExt());
            link.append('/'); //NOI18N
        }

        link.append(target.getNameExt());

        return link.toString();
    }

    /**
     * Converts given string into URL with all values properly encoded. May
     * return null if conversion fails.
     */
    public static URL stringToUrl(String urlString) {
        try {
            // #216436:
            // use URL to split the string into individual URI parts first:
            URL u;
            try {
                u = new URL(urlString);
            } catch (MalformedURLException ex) {
                // #219686 - try to use http protocol if protocol is missing:
                if (!(urlString.startsWith("file:/") ||
                    urlString.startsWith("http:/") ||
                    urlString.startsWith("https:/"))) {
                    urlString = "http://" + urlString;
                }
                u = new URL(urlString);
            }

            // do not use URI to encode JAR url and simply return it as is:
            if (urlString.startsWith("jar:")) { // NOI18N
                return u;
            }
            // and now use URI to properly encode spaces in path:
            return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toURL();
        } catch (URISyntaxException ex) {
            Exceptions.printStackTrace(ex);
        } catch (MalformedURLException ex) {
            Exceptions.printStackTrace(ex);
        }
        return null;
    }

    /**
     * Converts given URL into a String with all values decoded.
     */
    public static String urlToString(URL url) {
        return urlToString(url, false);
    }

    public static String urlToString(URL url, boolean pathOnly) {
        URI uri;
        try {
            uri = url.toURI();
        } catch (URISyntaxException ex) {
            // fallback:
            LOGGER.log(Level.FINE, "URL '"+url+"' cannot be converted to URI.");
            String res = url.toExternalForm();
            int end = res.lastIndexOf('?');
            if (end == -1) {
                end = res.lastIndexOf('#');
            }
            if (pathOnly && end != -1) {
                res = res.substring(0, end);
            }
            return res;
        }
        // do not use URI to encode JAR url and simply return it as is:
        if ("jar".equals(uri.getScheme())) { // NOI18N
            return uri.toASCIIString();
        }
        StringBuilder sb = new StringBuilder();
        sb.append(uri.getScheme());
        sb.append("://"); // NOI18N
        if (uri.getAuthority() != null) {
            sb.append(uri.getAuthority());
        }
        sb.append(uri.getPath());
        if (!pathOnly && uri.getQuery() != null) {
            sb.append("?"); // NOI18N
            sb.append(uri.getQuery());
        }
        if (!pathOnly && uri.getFragment() != null) {
            sb.append("#"); // NOI18N
            sb.append(uri.getFragment());
        }
        return sb.toString();
    }

    /**
     * Returns IP address of localhost in local network
     * @return
     */
    public static InetAddress getLocalhostInetAddress() {
        try {
            String inetAddr = System.getProperty("localhost.inet.address");
            if (inetAddr!=null) {
                return InetAddress.getByName(inetAddr);
            }
            InetAddress localHost = InetAddress.getLocalHost();
            if (!localHost.isLoopbackAddress()) {
                return localHost;
            }
            //workaround for strange behavior on debian, see #226087
            Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
            while (networkInterfaces.hasMoreElements()) {
                final NetworkInterface netInterface = networkInterfaces.nextElement();
                if (netInterface.isUp() && !netInterface.isLoopback() && !netInterface.isVirtual() && !netInterface.getName().startsWith("vbox")) {
                    Enumeration<InetAddress> inetAddresses = netInterface.getInetAddresses();
                    while (inetAddresses.hasMoreElements()) {
                        InetAddress nextElement = inetAddresses.nextElement();
                        if (!nextElement.isLoopbackAddress() && nextElement.isSiteLocalAddress()) {
                            return nextElement;
                        }

                    }
                }
            }
            return localHost;
        } catch (UnknownHostException uhex) {
            throw new IllegalStateException("Cannot resolve local host address, please check your network configuration.", uhex); // NOI18N
        } catch (SocketException ex) {
            throw new IllegalStateException(ex);
        }
    }

    /**
     * Checks whether the given project has web root.
     * @param project project to be checked
     * @return {@code true} if the given project has web root, {@code false} otherwise
     * @since 1.78
     */
    public static boolean hasWebRoot(Project project) {
        Parameters.notNull("project", project); // NOI18N
        ProjectWebRootProvider webRootProvider = project.getLookup().lookup(ProjectWebRootProvider.class);
        if (webRootProvider == null) {
            return false;
        }
        return !webRootProvider.getWebRoots().isEmpty();
    }

}
