/*
 * 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.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.sling.feature.ArtifactId;

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 an artifact id for the Apache Felix framework
     * @param version The version to use or {@code null} for the default version
     * @return The artifact id
     * @throws IllegalArgumentException If the provided version is invalid
     */
    public static ArtifactId getFelixFrameworkId(final String version) {
        return new ArtifactId("org.apache.felix",
                "org.apache.felix.framework",
                version != null ? version : "6.0.1", null, null);
    }

    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());
        }
    }
}
