/*
 * 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.analyser.task;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;

import org.apache.sling.feature.analyser.Analyser;

public final class AnalyzerTaskProvider {

    private AnalyzerTaskProvider() {
        // this class must not be instantiated directly
    }

    /**
     * Get all tasks. Calls {@code getTasksByIds(null, null)}.
     *
     * @return The analyser tasks, array is never {@code null} but might be empty
     */
    public static AnalyserTask[] getTasks() {
        return getTasksByIds(null, null);
    }

    /**
     * Get all tasks and obey the includes/excludes rules. If both includes and
     * excludes are null, method behaves like {@link #getTasks()}
     *
     * @param includes includes can be null, means "include everything"
     * @param excludes excludes can be null, means "do not exclude anything"
     * @return The analyser tasks, array is never {@code null} but might be empty
     * @throws IllegalStateException If an included task is not found
     */
    public static AnalyserTask[] getTasksByIds(Set<String> includes, Set<String> excludes) {
        if (excludes == null)
            excludes = Collections.emptySet();

        final ServiceLoader<AnalyserTask> loader = ServiceLoader.load(AnalyserTask.class);
        final Set<String> foundTasks = new HashSet<>();
        final List<AnalyserTask> list = new ArrayList<>();
        for(final AnalyserTask task : loader) {
            boolean included = includes != null ? includes.contains(task.getId()) : true;
            boolean excluded = excludes.contains(task.getId());

            if (included && !excluded) {
                list.add(task);
                foundTasks.add(task.getId());
            }
        }

        Set<String> notFoundTasks = new HashSet<>(includes != null ? includes : Collections.emptySet());
        notFoundTasks.removeAll(foundTasks);
        notFoundTasks.removeAll(excludes);
        if (notFoundTasks.size() > 0) {
            throw new IllegalStateException("Configured analyser task(s) not found: " + notFoundTasks);
        }

        return list.toArray(new AnalyserTask[list.size()]);
    }

    /**
     * Get tasks from class names
     *
     * @param taskClassNames The array of class names
     * @return The analyser tasks, array is never {@code null} but might be empty
     * @throws IOException If class names is null or loading fails
     */
    public static AnalyserTask[] getTasksByClassName(String...taskClassNames) throws IOException {
        if (taskClassNames == null) {
            throw new IOException("Impossible to load Tasks from a null string array");
        }

        List<AnalyserTask> list = new ArrayList<>();
        for (String cls : taskClassNames) {
            try {
                AnalyserTask task = (AnalyserTask) Analyser.class.getClassLoader().loadClass(cls).newInstance();
                list.add(task);
            } catch (Exception e) {
                throw new IOException(e);
            }
        }
        return list.toArray(new AnalyserTask[list.size()]);
    }

}
