/*
 * 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.sling.feature.io;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.jar.JarFile;

public class IOUtils {

    /** The extension for a reference file. */
    public static final String EXTENSION_REF_FILE = ".ref";

    /** The extension for a feature file. */
    public static final String EXTENSION_FEATURE_FILE = ".json";

    /** The default directory to search for features. */
    public static final String DEFAULT_DIRECTORY = "features";

    /** The default name of the feature file. */
    public static final String DEFAULT_FEATURE_FILE = "feature" + EXTENSION_FEATURE_FILE;

    /**
     * Parse a feature reference file
     * @param file The file
     * @return The referenced features
     * @throws IOException If reading fails
     */
    public static List<String> parseFeatureRefFile(final File file)
    throws IOException {
        final List<String> result = new ArrayList<>();
        final List<String> lines = Files.readAllLines(file.toPath());
        for(String line : lines) {
            line = line.trim();
            if ( !line.isEmpty() && !line.startsWith("#") ) {
                if ( line.indexOf(':') == -1 ) {
                    result.add(new File(line).getAbsolutePath());
                } else {
                    result.add(line);
                }
            }
        }
        return result;
    }

    /**
     * Get the list of feature files.
     * If the provided list of files is {@code null} or an empty array, the default is used.
     * The default checks for the following places, the first one found is used. If none is
     * found an empty list is returned.
     * <ol>
     *   <li>A directory named {@link #DEFAULT_DIRECTORY} in the current directory
     *   <li>A file named {@link #DEFAULT_FEATURE_FILE} in the current directory
     *   <li>A directory named {@link #DEFAULT_DIRECTORY} in the home directory
     *   <li>A file named {@link #DEFAULT_FEATURE_FILE} in the home directory
     * </ol>
     *
     * The list of files is processed one after the other. If it is relative, it is
     * first tried to be resolved against the current directory and then against the
     * home directory.
     * If an entry denotes a directory, all children ending in {@link #EXTENSION_FEATURE_FILE} or
     * {@link #EXTENSION_REF_FILE} of that directory are read.
     * If a file ends in {@link #EXTENSION_REF_FILE} the contents is read and every line not
     * starting with the hash sign is considered a reference to a feature artifact.
     *
     * @param homeDirectory If relative files should be resolved, this is the directory to use
     * @param files Optional list of files. If none is provided, a default is used.
     * @return The list of files.
     * @throws IOException If an error occurs.
     */
    public static List<String> getFeatureFiles(final File homeDirectory, final String... files)
    throws IOException {
        String[] featureFiles = files;
        if ( featureFiles == null || featureFiles.length == 0 ) {
            // Default value - check feature directory otherwise features file
            final File[] candidates = new File[] {
                    new File(homeDirectory, DEFAULT_DIRECTORY),
                    new File(homeDirectory, DEFAULT_FEATURE_FILE),
                    new File(DEFAULT_DIRECTORY),
                    new File(DEFAULT_FEATURE_FILE)
            };
            File f = null;
            for(final File c : candidates) {
                if ( c.exists() ) {
                    f = c;
                    break;
                }
            }
            // nothing found, we default to the first candidate and fail later
            if ( f == null ) {
                f = candidates[0];
            }

            featureFiles = new String[] {f.getAbsolutePath()};
        }

        final List<String> paths = new ArrayList<>();
        for(final String name : featureFiles) {
            // check for absolute
            if ( name.indexOf(':') > 1 ) {
                paths.add(name);
            } else {
                // file or relative
                File f = null;
                final File test = new File(name);
                if ( test.isAbsolute() ) {
                    f = test;
                } else {
                    final File[] candidates = {
                            new File(homeDirectory, name),
                            new File(homeDirectory, DEFAULT_DIRECTORY + File.separatorChar + name),
                            new File(name),
                            new File(DEFAULT_DIRECTORY + File.separatorChar + name),
                    };
                    for(final File c : candidates) {
                        if ( c.exists() && c.isFile() ) {
                            f = c;
                            break;
                        }
                    }
                }

                if ( f != null && f.exists() ) {
                    if ( f.isFile() ) {
                        processFile(paths, f);
                    } else {
                        processDir(paths, f);
                    }
                } else {
                    // we simply add the path and fail later on
                    paths.add(new File(name).getAbsolutePath());
                }
            }
        }

        Collections.sort(paths, FEATURE_PATH_COMP);
        return paths;
    }

    /**
     * Get a File from a local URL (if possible)
     *
     * @param url a local url (like a file: url or a jar:file: url
     * @param cache if an attempt should be made to download the content of the url locally
     *              if it can not be presented as a file directly
     * @param tmpDir the tmpDir to use (null for default)
     * @return the file the url points to (or null if none) - or a tmp file if cache is true and the url could be cached
     * @throws IOException
     */
    public static File getFileFromURL(URL url, boolean cache, File tmpDir) throws IOException {
        File result;
        if (url.getProtocol().equals("file")) {
            try {
                result = new File(url.toURI());
            } catch (URISyntaxException e) {
                result = new File(url.getPath());
            }
        } else if (url.getProtocol().equals("jar")) {
            String innerURL = url.getPath();
            if (innerURL.endsWith("!/") && innerURL.indexOf("!/") == innerURL.lastIndexOf("!/")) {
                innerURL = innerURL.substring(0, innerURL.indexOf("!/"));
                try {
                    result = getFileFromURL(new URL(innerURL), cache, tmpDir);
                } catch (IOException ex) {
                    result = null;
                }
            }
            else {
                result = null;
            }
        }
        else {
            result = null;
        }

        if ((result == null || !result.exists()) && cache) {
            File tmp = File.createTempFile("jar", ".jar", tmpDir);
            try (InputStream input = url.openStream(); OutputStream output = new FileOutputStream(tmp)) {
                byte[] buffer =new byte[64 * 1024];
                for (int i = input.read(buffer); i != -1;i = input.read(buffer)) {
                    output.write(buffer, 0, i);
                }
            }
            result = tmp;
        }
        return result;
    }

    /**
     * Get a JarFile from a local URL (if possible)
     *
     * @param url a local url (like a file: url or a jar:file: url
     * @param cache if an attempt should be made to download the content of the url locally
     *              if it can not be presented as a jarfile directly
     * @param tmpDir the tmpDir to use (null for default)
     *
     * @return the jarfile the url points to
     * @throws IOException if the url can't be represented as a jarfile
     */
    public static JarFile getJarFileFromURL(URL url, boolean cache, File tmpDir) throws IOException {
        try {
            URL targetURL = url;
            if (!url.getProtocol().equals("jar")) {
                targetURL = new URL("jar:" + toURLString(url) + "!/");
            }
            else if (!url.getPath().endsWith("!/")) {
                targetURL = new URL(toURLString(url) + "!/");
            }
            return ((JarURLConnection) targetURL.openConnection()).getJarFile();
        } catch (IOException ex) {
            File file = getFileFromURL(url, cache, tmpDir);
            if (file != null) {
                return new JarFile(file);
            }
            else {
                throw ex;
            }
        }
    }

    private static String toURLString(URL url) {
        try {
            return url.toURI().toURL().toString();
        } catch (URISyntaxException | MalformedURLException e) {
            return url.toString();
        }
    }
    static final Comparator<String> FEATURE_PATH_COMP = new Comparator<String>() {
        @Override
        public int compare(final String o1, final String o2) {
            // windows path conversion
            final String key1 = o1.replace(File.separatorChar, '/');
            final String key2 = o2.replace(File.separatorChar, '/');

            final int lastSlash1 = key1.lastIndexOf('/');
            final int lastSlash2 = key2.lastIndexOf('/');
            if ( lastSlash1 == -1 || lastSlash2 == -1 ) {
                return o1.compareTo(o2);
            }
            final String path1 = key1.substring(0, lastSlash1 + 1);
            final String path2 = key2.substring(0, lastSlash2 + 1);
            if ( path1.equals(path2) ) {
                return o1.compareTo(o2);
            }
            if ( path1.startsWith(path2) ) {
                return 1;
            } else if ( path2.startsWith(path1) ) {
                return -1;
            }
            return o1.compareTo(o2);
        }
    };

    private static void processDir(final List<String> paths, final File dir)
    throws IOException {
        for(final File f : dir.listFiles()) {
            if ( f.isFile() && !f.getName().startsWith(".")) {
                // check if file is a reference
                if ( f.getName().endsWith(EXTENSION_REF_FILE) || f.getName().endsWith(EXTENSION_FEATURE_FILE) ) {
                    processFile(paths, f);
                }
            }
        }
    }

    private static void processFile(final List<String> paths, final File f)
    throws IOException {
        if ( f.getName().endsWith(EXTENSION_REF_FILE) ) {
            paths.addAll(parseFeatureRefFile(f));
        } else {
            paths.add(f.getAbsolutePath());
        }
    }
}
