/*
 * 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;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.maven.lifecycle.internal.ExecutionPlanItem;
import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.descriptor.MojoDescriptor;

// TODO lifecycles being executed
// TODO what runs in each phase
// TODO plugins that need downloading
// TODO project dependencies that need downloading
// TODO unfortunately the plugins need to be downloaded in order to get the plugin.xml file. need to externalize this
//      from the plugin archive.
// TODO this will be the class that people get in IDEs to modify

/**
 * MavenExecutionPlan
 */
public class MavenExecutionPlan implements Iterable<ExecutionPlanItem> {

    /*
      At the moment, this class is totally immutable, and this is in line with thoughts about the
      pre-calculated execution plan that stays the same during the execution.

      If deciding to add mutable state to this class, it should be at least considered to
      separate this into a separate mutable structure.

    */

    private final List<ExecutionPlanItem> planItem;

    private final Map<String, ExecutionPlanItem> lastMojoExecutionForAllPhases;

    final List<String> phasesInExecutionPlan;

    public MavenExecutionPlan(List<ExecutionPlanItem> planItem, DefaultLifecycles defaultLifecycles) {
        this.planItem = planItem;

        lastMojoExecutionForAllPhases = new LinkedHashMap<>();

        LinkedHashSet<String> totalPhaseSet = new LinkedHashSet<>();
        if (defaultLifecycles != null) {
            for (String phase : getDistinctPhasesInOrderOfExecutionPlanAppearance(planItem)) {
                final Lifecycle lifecycle = defaultLifecycles.get(phase);
                if (lifecycle != null) {
                    totalPhaseSet.addAll(lifecycle.getPhases());
                }
            }
        }
        this.phasesInExecutionPlan = new ArrayList<>(totalPhaseSet);

        Map<String, ExecutionPlanItem> lastInExistingPhases = new HashMap<>();
        for (ExecutionPlanItem executionPlanItem : getExecutionPlanItems()) {
            lastInExistingPhases.put(executionPlanItem.getLifecyclePhase(), executionPlanItem);
        }

        ExecutionPlanItem lastSeenExecutionPlanItem = null;

        for (String phase : totalPhaseSet) {
            ExecutionPlanItem forThisPhase = lastInExistingPhases.get(phase);
            if (forThisPhase != null) {
                lastSeenExecutionPlanItem = forThisPhase;
            }

            lastMojoExecutionForAllPhases.put(phase, lastSeenExecutionPlanItem);
        }
    }

    public Iterator<ExecutionPlanItem> iterator() {
        return getExecutionPlanItems().iterator();
    }

    /**
     * Returns the last ExecutionPlanItem in the supplied phase. If no items are in the specified phase,
     * the closest executionPlanItem from an earlier phase item will be returned.
     *
     * @param requestedPhase the requested phase
     *                       The execution plan item
     * @return The ExecutionPlanItem or null if none can be found
     */
    public ExecutionPlanItem findLastInPhase(String requestedPhase) {
        return lastMojoExecutionForAllPhases.get(requestedPhase);
    }

    private List<ExecutionPlanItem> getExecutionPlanItems() {
        return planItem;
    }

    private static Iterable<String> getDistinctPhasesInOrderOfExecutionPlanAppearance(
            List<ExecutionPlanItem> planItems) {
        LinkedHashSet<String> result = new LinkedHashSet<>();
        for (ExecutionPlanItem executionPlanItem : planItems) {
            final String phase = executionPlanItem.getLifecyclePhase();
            if (!result.contains(phase)) {
                result.add(phase);
            }
        }
        return result;
    }

    public List<MojoExecution> getMojoExecutions() {
        List<MojoExecution> result = new ArrayList<>();
        for (ExecutionPlanItem executionPlanItem : planItem) {
            result.add(executionPlanItem.getMojoExecution());
        }
        return result;
    }

    /**
     * Get set of plugins having a goal/mojo used but not marked @threadSafe
     *
     * @return the set of plugins (without info on which goal is concerned)
     */
    public Set<Plugin> getNonThreadSafePlugins() {
        Set<Plugin> plugins = new HashSet<>();
        for (ExecutionPlanItem executionPlanItem : planItem) {
            final MojoExecution mojoExecution = executionPlanItem.getMojoExecution();
            if (!mojoExecution.getMojoDescriptor().isThreadSafe()) {
                plugins.add(mojoExecution.getPlugin());
            }
        }
        return plugins;
    }

    /**
     * Get set of mojos used but not marked @threadSafe
     *
     * @return the set of mojo descriptors
     */
    public Set<MojoDescriptor> getNonThreadSafeMojos() {
        Set<MojoDescriptor> mojos = new HashSet<>();
        for (ExecutionPlanItem executionPlanItem : planItem) {
            final MojoExecution mojoExecution = executionPlanItem.getMojoExecution();
            if (!mojoExecution.getMojoDescriptor().isThreadSafe()) {
                mojos.add(mojoExecution.getMojoDescriptor());
            }
        }
        return mojos;
    }

    // Used by m2e but will be removed, really.
    @Deprecated
    public List<MojoExecution> getExecutions() {
        return getMojoExecutions();
    }

    public int size() {
        return planItem.size();
    }
}
