/*
 * 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.maven.lifecycle.internal.builder.multithreaded;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.execution.ProjectDependencyGraph;
import org.apache.maven.lifecycle.internal.ProjectBuildList;
import org.apache.maven.lifecycle.internal.ProjectSegment;
import org.apache.maven.project.MavenProject;

/**
 * <p>
 * Presents a view of the Dependency Graph that is suited for concurrent building.
 * </p>
 * <strong>NOTE:</strong> This class is not part of any public api and can be changed or deleted without prior notice.
 *
 * @since 3.0
 */
public class ConcurrencyDependencyGraph {

    private final ProjectBuildList projectBuilds;

    private final ProjectDependencyGraph projectDependencyGraph;

    private final Set<MavenProject> finishedProjects = new HashSet<>();

    public ConcurrencyDependencyGraph(ProjectBuildList projectBuilds, ProjectDependencyGraph projectDependencyGraph) {
        this.projectDependencyGraph = projectDependencyGraph;
        this.projectBuilds = projectBuilds;
    }

    public int getNumberOfBuilds() {
        return projectBuilds.size();
    }

    /**
     * Gets all the builds that have no reactor-dependencies
     *
     * @return A set of all the initial builds
     */
    public List<MavenProject> getRootSchedulableBuilds() {
        Set<MavenProject> result = new LinkedHashSet<>();
        for (ProjectSegment projectBuild : projectBuilds) {
            if (projectDependencyGraph
                    .getUpstreamProjects(projectBuild.getProject(), false)
                    .isEmpty()) {
                result.add(projectBuild.getProject());
            }
        }
        if (result.isEmpty() && projectBuilds.size() > 0) {
            // Must return at least one project
            result.add(projectBuilds.get(0).getProject());
        }
        return new ArrayList<>(result);
    }

    /**
     * Marks the provided project as finished. Returns a list of
     *
     * @param mavenProject The project
     * @return The list of builds that are eligible for starting now that the provided project is done
     */
    public List<MavenProject> markAsFinished(MavenProject mavenProject) {
        finishedProjects.add(mavenProject);
        return getSchedulableNewProcesses(mavenProject);
    }

    private List<MavenProject> getSchedulableNewProcesses(MavenProject finishedProject) {
        List<MavenProject> result = new ArrayList<>();
        // schedule dependent projects, if all of their requirements are met
        for (MavenProject dependentProject : projectDependencyGraph.getDownstreamProjects(finishedProject, false)) {
            final List<MavenProject> upstreamProjects =
                    projectDependencyGraph.getUpstreamProjects(dependentProject, false);
            if (finishedProjects.containsAll(upstreamProjects)) {
                result.add(dependentProject);
            }
        }
        return result;
    }

    /**
     * @return set of projects that have yet to be processed successfully by the build.
     */
    public Set<MavenProject> getUnfinishedProjects() {
        Set<MavenProject> unfinished = new HashSet<>(projectBuilds.getProjects());
        unfinished.removeAll(finishedProjects);
        return unfinished;
    }

    /**
     * @return set of projects that have been successfully processed by the build.
     */
    protected Set<MavenProject> getFinishedProjects() {
        return finishedProjects;
    }

    protected ProjectBuildList getProjectBuilds() {
        return projectBuilds;
    }

    /**
     * For the given {@link MavenProject} {@code p}, return all of {@code p}'s dependencies.
     *
     * @param p
     * @return List of prerequisite projects
     */
    protected List<MavenProject> getDependencies(MavenProject p) {
        return projectDependencyGraph.getUpstreamProjects(p, false);
    }

    /**
     * For the given {@link MavenProject} {@code p} return {@code p}'s uncompleted dependencies.
     *
     * @param p
     * @return List of uncompleted prerequisite projects
     */
    public List<MavenProject> getActiveDependencies(MavenProject p) {
        List<MavenProject> activeDependencies = projectDependencyGraph.getUpstreamProjects(p, false);
        activeDependencies.removeAll(finishedProjects);
        return activeDependencies;
    }
}
