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

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import java.util.Collection;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.api.xml.XmlNode;
import org.apache.maven.internal.impl.DefaultMessageBuilderFactory;
import org.apache.maven.internal.xml.XmlNodeImpl;
import org.apache.maven.lifecycle.MojoExecutionConfigurator;
import org.apache.maven.model.Plugin;
import org.apache.maven.model.PluginExecution;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static java.util.Arrays.stream;
import static java.util.Objects.requireNonNull;

/**
 * @since 3.3.1, MNG-5753
 */
@Named
@Singleton
public class DefaultMojoExecutionConfigurator implements MojoExecutionConfigurator {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final MessageBuilderFactory messageBuilderFactory;

    /**
     * Default ctor is used in IT and most probably some 3rd party code. For those cases, we do provide sane defaults
     * but given this is a component, injection should be used, replacing direct instantiation.
     *
     * @deprecated Do not use this ctor directly, inject this component instead.
     */
    @Deprecated
    public DefaultMojoExecutionConfigurator() {
        this.messageBuilderFactory = new DefaultMessageBuilderFactory();
    }

    @Inject
    public DefaultMojoExecutionConfigurator(MessageBuilderFactory messageBuilderFactory) {
        this.messageBuilderFactory = requireNonNull(messageBuilderFactory);
    }

    @Override
    public void configure(MavenProject project, MojoExecution mojoExecution, boolean allowPluginLevelConfig) {
        String g = mojoExecution.getPlugin().getGroupId();

        String a = mojoExecution.getPlugin().getArtifactId();

        Plugin plugin = findPlugin(g, a, project.getBuildPlugins());

        if (plugin == null && project.getPluginManagement() != null) {
            plugin = findPlugin(g, a, project.getPluginManagement().getPlugins());
        }

        if (plugin != null) {
            PluginExecution pluginExecution =
                    findPluginExecution(mojoExecution.getExecutionId(), plugin.getExecutions());

            XmlNode pomConfiguration = null;

            if (pluginExecution != null) {
                pomConfiguration = pluginExecution.getDelegate().getConfiguration();
            } else if (allowPluginLevelConfig) {
                pomConfiguration = plugin.getDelegate().getConfiguration();
            }

            XmlNode mojoConfiguration = mojoExecution.getConfiguration() != null
                    ? mojoExecution.getConfiguration().getDom()
                    : null;

            XmlNode mergedConfiguration = XmlNodeImpl.merge(mojoConfiguration, pomConfiguration);

            mojoExecution.setConfiguration(mergedConfiguration);

            checkUnknownMojoConfigurationParameters(mojoExecution);
        }
    }

    private Plugin findPlugin(String groupId, String artifactId, Collection<Plugin> plugins) {
        for (Plugin plugin : plugins) {
            if (artifactId.equals(plugin.getArtifactId()) && groupId.equals(plugin.getGroupId())) {
                return plugin;
            }
        }

        return null;
    }

    private PluginExecution findPluginExecution(String executionId, Collection<PluginExecution> executions) {
        if (executionId != null && !executionId.isEmpty()) {
            for (PluginExecution execution : executions) {
                if (executionId.equals(execution.getId())) {
                    return execution;
                }
            }
        }

        return null;
    }

    private void checkUnknownMojoConfigurationParameters(MojoExecution mojoExecution) {
        if (mojoExecution.getConfiguration() == null
                || mojoExecution.getConfiguration().getChildCount() == 0) {
            return;
        }

        MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();

        // in first step get parameter names of current goal
        Set<String> parametersNamesGoal = mojoDescriptor.getParameters().stream()
                .flatMap(this::getParameterNames)
                .collect(Collectors.toSet());

        Set<String> unknownParameters = getUnknownParameters(mojoExecution, parametersNamesGoal);

        if (unknownParameters.isEmpty()) {
            return;
        }

        // second step get parameter names of all plugin goals
        Set<String> parametersNamesAll = mojoDescriptor.getPluginDescriptor().getMojos().stream()
                .flatMap(m -> m.getParameters().stream())
                .flatMap(this::getParameterNames)
                .collect(Collectors.toSet());

        unknownParameters = getUnknownParameters(mojoExecution, parametersNamesAll);

        unknownParameters.forEach(name -> {
            MessageBuilder messageBuilder = messageBuilderFactory
                    .builder()
                    .warning("Parameter '")
                    .warning(name)
                    .warning("' is unknown for plugin '")
                    .warning(mojoExecution.getArtifactId())
                    .warning(":")
                    .warning(mojoExecution.getVersion())
                    .warning(":")
                    .warning(mojoExecution.getGoal());

            if (mojoExecution.getExecutionId() != null) {
                messageBuilder.warning(" (");
                messageBuilder.warning(mojoExecution.getExecutionId());
                messageBuilder.warning(")");
            }

            messageBuilder.warning("'");

            logger.warn(messageBuilder.toString());
        });
    }

    private Stream<String> getParameterNames(Parameter parameter) {
        if (parameter.getAlias() != null) {
            return Stream.of(parameter.getName(), parameter.getAlias());
        } else {
            return Stream.of(parameter.getName());
        }
    }

    private Set<String> getUnknownParameters(MojoExecution mojoExecution, Set<String> parameters) {
        return stream(mojoExecution.getConfiguration().getChildren())
                .map(Xpp3Dom::getName)
                .filter(name -> !parameters.contains(name))
                .collect(Collectors.toSet());
    }
}
