/*
 * 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.artifact.resolver;

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

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;

import org.apache.maven.RepositoryUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.metadata.ResolutionGroup;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.LegacyLocalRepositoryManager;
import org.apache.maven.artifact.repository.RepositoryRequest;
import org.apache.maven.artifact.repository.metadata.Snapshot;
import org.apache.maven.artifact.repository.metadata.SnapshotArtifactRepositoryMetadata;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.LegacySupport;
import org.apache.maven.repository.legacy.metadata.DefaultMetadataResolutionRequest;
import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest;
import org.apache.maven.repository.legacy.resolver.conflict.ConflictResolver;
import org.apache.maven.wagon.events.TransferListener;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResult;

/**
 */
@Named
@Singleton
@Deprecated
public class DefaultArtifactResolver implements ArtifactResolver, Disposable {
    @Inject
    private Logger logger;

    @Inject
    protected ArtifactFactory artifactFactory;

    @Inject
    private ArtifactCollector artifactCollector;

    @Inject
    private ResolutionErrorHandler resolutionErrorHandler;

    @Inject
    private ArtifactMetadataSource source;

    @Inject
    private PlexusContainer container;

    @Inject
    private LegacySupport legacySupport;

    private final Executor executor;

    public DefaultArtifactResolver() {
        int threads = Integer.getInteger("maven.artifact.threads", 5);
        if (threads <= 1) {
            executor = Runnable::run;
        } else {
            executor = new ThreadPoolExecutor(
                    threads, threads, 3, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new DaemonThreadCreator());
        }
    }

    private RepositorySystemSession getSession(ArtifactRepository localRepository) {
        return LegacyLocalRepositoryManager.overlay(localRepository, legacySupport.getRepositorySession(), null);
    }

    private void injectSession1(RepositoryRequest request, MavenSession session) {
        if (session != null) {
            request.setOffline(session.isOffline());
            request.setForceUpdate(session.getRequest().isUpdateSnapshots());
        }
    }

    private void injectSession2(ArtifactResolutionRequest request, MavenSession session) {
        injectSession1(request, session);

        if (session != null) {
            request.setServers(session.getRequest().getServers());
            request.setMirrors(session.getRequest().getMirrors());
            request.setProxies(session.getRequest().getProxies());
        }
    }

    public void resolve(
            Artifact artifact,
            List<ArtifactRepository> remoteRepositories,
            ArtifactRepository localRepository,
            TransferListener resolutionListener)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        resolve(artifact, remoteRepositories, getSession(localRepository));
    }

    public void resolveAlways(
            Artifact artifact, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        resolve(artifact, remoteRepositories, getSession(localRepository));
    }

    private void resolve(
            Artifact artifact, List<ArtifactRepository> remoteRepositories, RepositorySystemSession session)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        if (artifact == null) {
            return;
        }

        if (Artifact.SCOPE_SYSTEM.equals(artifact.getScope())) {
            File systemFile = artifact.getFile();

            if (systemFile == null) {
                throw new ArtifactNotFoundException("System artifact: " + artifact + " has no file attached", artifact);
            }

            if (!systemFile.exists()) {
                throw new ArtifactNotFoundException(
                        "System artifact: " + artifact + " not found in path: " + systemFile, artifact);
            }

            if (!systemFile.isFile()) {
                throw new ArtifactNotFoundException(
                        "System artifact: " + artifact + " is not a file: " + systemFile, artifact);
            }

            artifact.setResolved(true);

            return;
        }

        if (!artifact.isResolved()) {
            ArtifactResult result;

            try {
                ArtifactRequest artifactRequest = new ArtifactRequest();
                artifactRequest.setArtifact(RepositoryUtils.toArtifact(artifact));
                artifactRequest.setRepositories(RepositoryUtils.toRepos(remoteRepositories));

                // Maven 2.x quirk: an artifact always points at the local repo, regardless whether resolved or not
                LocalRepositoryManager lrm = session.getLocalRepositoryManager();
                String path = lrm.getPathForLocalArtifact(artifactRequest.getArtifact());
                artifact.setFile(new File(lrm.getRepository().getBasedir(), path));

                RepositorySystem repoSystem = container.lookup(RepositorySystem.class);
                result = repoSystem.resolveArtifact(session, artifactRequest);
            } catch (ComponentLookupException e) {
                throw new IllegalStateException("Unable to lookup " + RepositorySystem.class.getName());
            } catch (org.eclipse.aether.resolution.ArtifactResolutionException e) {
                if (e.getCause() instanceof org.eclipse.aether.transfer.ArtifactNotFoundException) {
                    throw new ArtifactNotFoundException(e.getMessage(), artifact, remoteRepositories, e);
                } else {
                    throw new ArtifactResolutionException(e.getMessage(), artifact, remoteRepositories, e);
                }
            }

            artifact.selectVersion(result.getArtifact().getVersion());
            artifact.setFile(result.getArtifact().getFile());
            artifact.setResolved(true);

            if (artifact.isSnapshot()) {
                Matcher matcher = Artifact.VERSION_FILE_PATTERN.matcher(artifact.getVersion());
                if (matcher.matches()) {
                    Snapshot snapshot = new Snapshot();
                    snapshot.setTimestamp(matcher.group(2));
                    try {
                        snapshot.setBuildNumber(Integer.parseInt(matcher.group(3)));
                        artifact.addMetadata(new SnapshotArtifactRepositoryMetadata(artifact, snapshot));
                    } catch (NumberFormatException e) {
                        logger.warn("Invalid artifact version " + artifact.getVersion() + ": " + e.getMessage());
                    }
                }
            }
        }
    }

    public ArtifactResolutionResult resolveTransitively(
            Set<Artifact> artifacts,
            Artifact originatingArtifact,
            ArtifactRepository localRepository,
            List<ArtifactRepository> remoteRepositories,
            ArtifactMetadataSource source,
            ArtifactFilter filter)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        return resolveTransitively(
                artifacts,
                originatingArtifact,
                Collections.emptyMap(),
                localRepository,
                remoteRepositories,
                source,
                filter);
    }

    public ArtifactResolutionResult resolveTransitively(
            Set<Artifact> artifacts,
            Artifact originatingArtifact,
            Map<String, Artifact> managedVersions,
            ArtifactRepository localRepository,
            List<ArtifactRepository> remoteRepositories,
            ArtifactMetadataSource source)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        return resolveTransitively(
                artifacts, originatingArtifact, managedVersions, localRepository, remoteRepositories, source, null);
    }

    public ArtifactResolutionResult resolveTransitively(
            Set<Artifact> artifacts,
            Artifact originatingArtifact,
            Map<String, Artifact> managedVersions,
            ArtifactRepository localRepository,
            List<ArtifactRepository> remoteRepositories,
            ArtifactMetadataSource source,
            ArtifactFilter filter)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        return resolveTransitively(
                artifacts,
                originatingArtifact,
                managedVersions,
                localRepository,
                remoteRepositories,
                source,
                filter,
                null);
    }

    public ArtifactResolutionResult resolveTransitively(
            Set<Artifact> artifacts,
            Artifact originatingArtifact,
            List<ArtifactRepository> remoteRepositories,
            ArtifactRepository localRepository,
            ArtifactMetadataSource source)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        return resolveTransitively(artifacts, originatingArtifact, localRepository, remoteRepositories, source, null);
    }

    public ArtifactResolutionResult resolveTransitively(
            Set<Artifact> artifacts,
            Artifact originatingArtifact,
            List<ArtifactRepository> remoteRepositories,
            ArtifactRepository localRepository,
            ArtifactMetadataSource source,
            List<ResolutionListener> listeners)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        return resolveTransitively(
                artifacts,
                originatingArtifact,
                Collections.emptyMap(),
                localRepository,
                remoteRepositories,
                source,
                null,
                listeners);
    }

    @SuppressWarnings("checkstyle:parameternumber")
    public ArtifactResolutionResult resolveTransitively(
            Set<Artifact> artifacts,
            Artifact originatingArtifact,
            Map<String, Artifact> managedVersions,
            ArtifactRepository localRepository,
            List<ArtifactRepository> remoteRepositories,
            ArtifactMetadataSource source,
            ArtifactFilter filter,
            List<ResolutionListener> listeners)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        return resolveTransitively(
                artifacts,
                originatingArtifact,
                managedVersions,
                localRepository,
                remoteRepositories,
                source,
                filter,
                listeners,
                null);
    }

    @SuppressWarnings("checkstyle:parameternumber")
    public ArtifactResolutionResult resolveTransitively(
            Set<Artifact> artifacts,
            Artifact originatingArtifact,
            Map<String, Artifact> managedVersions,
            ArtifactRepository localRepository,
            List<ArtifactRepository> remoteRepositories,
            ArtifactMetadataSource source,
            ArtifactFilter filter,
            List<ResolutionListener> listeners,
            List<ConflictResolver> conflictResolvers)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        ArtifactResolutionRequest request = new ArtifactResolutionRequest()
                .setArtifact(originatingArtifact)
                .setResolveRoot(false)
                .
                // This is required by the surefire plugin
                setArtifactDependencies(artifacts)
                .setManagedVersionMap(managedVersions)
                .setLocalRepository(localRepository)
                .setRemoteRepositories(remoteRepositories)
                .setCollectionFilter(filter)
                .setListeners(listeners);

        injectSession2(request, legacySupport.getSession());

        return resolveWithExceptions(request);
    }

    public ArtifactResolutionResult resolveWithExceptions(ArtifactResolutionRequest request)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        ArtifactResolutionResult result = resolve(request);

        // We have collected all the problems so let's mimic the way the old code worked and just blow up right here.
        // That's right lets just let it rip right here and send a big incomprehensible blob of text at unsuspecting
        // users. Bad dog!

        resolutionErrorHandler.throwErrors(request, result);

        return result;
    }

    // ------------------------------------------------------------------------
    //
    // ------------------------------------------------------------------------

    @SuppressWarnings("checkstyle:methodlength")
    public ArtifactResolutionResult resolve(ArtifactResolutionRequest request) {
        Artifact rootArtifact = request.getArtifact();
        Set<Artifact> artifacts = request.getArtifactDependencies();
        Map<String, Artifact> managedVersions = request.getManagedVersionMap();
        List<ResolutionListener> listeners = request.getListeners();
        ArtifactFilter collectionFilter = request.getCollectionFilter();
        ArtifactFilter resolutionFilter = request.getResolutionFilter();
        RepositorySystemSession session = getSession(request.getLocalRepository());

        // TODO: hack because metadata isn't generated in m2e correctly and i want to run the maven i have in the
        // workspace
        if (source == null) {
            try {
                source = container.lookup(ArtifactMetadataSource.class);
            } catch (ComponentLookupException e) {
                // won't happen
            }
        }

        if (listeners == null) {
            listeners = new ArrayList<>();

            if (logger.isDebugEnabled()) {
                listeners.add(new DebugResolutionListener(logger));
            }

            listeners.add(new WarningResolutionListener(logger));
        }

        ArtifactResolutionResult result = new ArtifactResolutionResult();

        // The root artifact may, or may not be resolved so we need to check before we attempt to resolve.
        // This is often an artifact like a POM that is taken from disk and we already have hold of the
        // file reference. But this may be a Maven Plugin that we need to resolve from a remote repository
        // as well as its dependencies.

        if (request.isResolveRoot() /* && rootArtifact.getFile() == null */) {
            try {
                resolve(rootArtifact, request.getRemoteRepositories(), session);
            } catch (ArtifactResolutionException e) {
                result.addErrorArtifactException(e);
                return result;
            } catch (ArtifactNotFoundException e) {
                result.addMissingArtifact(request.getArtifact());
                return result;
            }
        }

        ArtifactResolutionRequest collectionRequest = request;

        if (request.isResolveTransitively()) {
            MetadataResolutionRequest metadataRequest = new DefaultMetadataResolutionRequest(request);

            metadataRequest.setArtifact(rootArtifact);
            metadataRequest.setResolveManagedVersions(managedVersions == null);

            try {
                ResolutionGroup resolutionGroup = source.retrieve(metadataRequest);

                if (managedVersions == null) {
                    managedVersions = resolutionGroup.getManagedVersions();
                }

                Set<Artifact> directArtifacts = resolutionGroup.getArtifacts();

                if (artifacts == null || artifacts.isEmpty()) {
                    artifacts = directArtifacts;
                } else {
                    List<Artifact> allArtifacts = new ArrayList<>();
                    allArtifacts.addAll(artifacts);
                    allArtifacts.addAll(directArtifacts);

                    Map<String, Artifact> mergedArtifacts = new LinkedHashMap<>();
                    for (Artifact artifact : allArtifacts) {
                        String conflictId = artifact.getDependencyConflictId();
                        if (!mergedArtifacts.containsKey(conflictId)) {
                            mergedArtifacts.put(conflictId, artifact);
                        }
                    }

                    artifacts = new LinkedHashSet<>(mergedArtifacts.values());
                }

                collectionRequest = new ArtifactResolutionRequest(request);
                collectionRequest.setServers(request.getServers());
                collectionRequest.setMirrors(request.getMirrors());
                collectionRequest.setProxies(request.getProxies());
                collectionRequest.setRemoteRepositories(resolutionGroup.getResolutionRepositories());
            } catch (ArtifactMetadataRetrievalException e) {
                ArtifactResolutionException are = new ArtifactResolutionException(
                        "Unable to get dependency information for " + rootArtifact.getId() + ": " + e.getMessage(),
                        rootArtifact,
                        metadataRequest.getRemoteRepositories(),
                        e);
                result.addMetadataResolutionException(are);
                return result;
            }
        }

        if (artifacts == null || artifacts.isEmpty()) {
            if (request.isResolveRoot()) {
                result.addArtifact(rootArtifact);
            }
            return result;
        }

        // After the collection we will have the artifact object in the result but they will not be resolved yet.
        result = artifactCollector.collect(
                artifacts, rootArtifact, managedVersions, collectionRequest, source, collectionFilter, listeners, null);

        // We have metadata retrieval problems, or there are cycles that have been detected
        // so we give this back to the calling code and let them deal with this information
        // appropriately.

        if (result.hasMetadataResolutionExceptions()
                || result.hasVersionRangeViolations()
                || result.hasCircularDependencyExceptions()) {
            return result;
        }

        if (result.getArtifactResolutionNodes() != null) {
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

            CountDownLatch latch =
                    new CountDownLatch(result.getArtifactResolutionNodes().size());

            for (ResolutionNode node : result.getArtifactResolutionNodes()) {
                Artifact artifact = node.getArtifact();

                if (resolutionFilter == null || resolutionFilter.include(artifact)) {
                    executor.execute(new ResolveTask(
                            classLoader, latch, artifact, session, node.getRemoteRepositories(), result));
                } else {
                    latch.countDown();
                }
            }
            try {
                latch.await();
            } catch (InterruptedException e) {
                result.addErrorArtifactException(
                        new ArtifactResolutionException("Resolution interrupted", rootArtifact, e));
            }
        }

        // We want to send the root artifact back in the result but we need to do this after the other dependencies
        // have been resolved.
        if (request.isResolveRoot()) {
            // Add the root artifact (as the first artifact to retain logical order of class path!)
            Set<Artifact> allArtifacts = new LinkedHashSet<>();
            allArtifacts.add(rootArtifact);
            allArtifacts.addAll(result.getArtifacts());
            result.setArtifacts(allArtifacts);
        }

        return result;
    }

    public void resolve(
            Artifact artifact, List<ArtifactRepository> remoteRepositories, ArtifactRepository localRepository)
            throws ArtifactResolutionException, ArtifactNotFoundException {
        resolve(artifact, remoteRepositories, localRepository, null);
    }

    /**
     * ThreadCreator for creating daemon threads with fixed ThreadGroup-name.
     */
    static final class DaemonThreadCreator implements ThreadFactory {
        static final String THREADGROUP_NAME = "org.apache.maven.artifact.resolver.DefaultArtifactResolver";

        static final ThreadGroup GROUP = new ThreadGroup(THREADGROUP_NAME);

        static final AtomicInteger THREAD_NUMBER = new AtomicInteger(1);

        public Thread newThread(Runnable r) {
            Thread newThread = new Thread(GROUP, r, "resolver-" + THREAD_NUMBER.getAndIncrement());
            newThread.setDaemon(true);
            newThread.setContextClassLoader(null);
            return newThread;
        }
    }

    private class ResolveTask implements Runnable {

        private final ClassLoader classLoader;

        private final CountDownLatch latch;

        private final Artifact artifact;

        private final RepositorySystemSession session;

        private final List<ArtifactRepository> remoteRepositories;

        private final ArtifactResolutionResult result;

        ResolveTask(
                ClassLoader classLoader,
                CountDownLatch latch,
                Artifact artifact,
                RepositorySystemSession session,
                List<ArtifactRepository> remoteRepositories,
                ArtifactResolutionResult result) {
            this.classLoader = classLoader;
            this.latch = latch;
            this.artifact = artifact;
            this.session = session;
            this.remoteRepositories = remoteRepositories;
            this.result = result;
        }

        public void run() {
            ClassLoader old = Thread.currentThread().getContextClassLoader();
            try {
                Thread.currentThread().setContextClassLoader(classLoader);
                resolve(artifact, remoteRepositories, session);
            } catch (ArtifactNotFoundException anfe) {
                // These are cases where the artifact just isn't present in any of the remote repositories
                // because it wasn't deployed, or it was deployed in the wrong place.

                synchronized (result) {
                    result.addMissingArtifact(artifact);
                }
            } catch (ArtifactResolutionException e) {
                // This is really a wagon TransferFailedException so something went wrong after we successfully
                // retrieved the metadata.

                synchronized (result) {
                    result.addErrorArtifactException(e);
                }
            } finally {
                latch.countDown();
                Thread.currentThread().setContextClassLoader(old);
            }
        }
    }

    @Override
    public void dispose() {
        if (executor instanceof ExecutorService) {
            ((ExecutorService) executor).shutdownNow();
        }
    }
}
