package org.apache.maven;

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

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.ArtifactProperties;
import org.eclipse.aether.artifact.ArtifactType;
import org.eclipse.aether.artifact.ArtifactTypeRegistry;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.artifact.DefaultArtifactType;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.graph.Exclusion;
import org.eclipse.aether.repository.Authentication;
import org.eclipse.aether.repository.Proxy;
import org.eclipse.aether.repository.RemoteRepository;
import org.eclipse.aether.repository.RepositoryPolicy;
import org.eclipse.aether.repository.WorkspaceReader;
import org.eclipse.aether.repository.WorkspaceRepository;
import org.eclipse.aether.util.repository.AuthenticationBuilder;

/**
 * <strong>Warning:</strong> This is an internal utility class that is only public for technical reasons, it is not part
 * of the public API. In particular, this class can be changed or deleted without prior notice.
 *
 * @author Benjamin Bentmann
 */
public class RepositoryUtils
{

    private static String nullify( String string )
    {
        return ( string == null || string.length() <= 0 ) ? null : string;
    }

    private static org.apache.maven.artifact.Artifact toArtifact( Dependency dependency )
    {
        if ( dependency == null )
        {
            return null;
        }

        org.apache.maven.artifact.Artifact result = toArtifact( dependency.getArtifact() );
        result.setScope( dependency.getScope() );
        result.setOptional( dependency.isOptional() );

        return result;
    }

    public static org.apache.maven.artifact.Artifact toArtifact( Artifact artifact )
    {
        if ( artifact == null )
        {
            return null;
        }

        ArtifactHandler handler = newHandler( artifact );

        /*
         * NOTE: From Artifact.hasClassifier(), an empty string and a null both denote "no classifier". However, some
         * plugins only check for null, so be sure to nullify an empty classifier.
         */
        org.apache.maven.artifact.Artifact result =
            new org.apache.maven.artifact.DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(),
                                                           artifact.getVersion(), null,
                                                           artifact.getProperty( ArtifactProperties.TYPE,
                                                                                 artifact.getExtension() ),
                                                           nullify( artifact.getClassifier() ), handler );

        result.setFile( artifact.getFile() );
        result.setResolved( artifact.getFile() != null );

        List<String> trail = new ArrayList<>( 1 );
        trail.add( result.getId() );
        result.setDependencyTrail( trail );

        return result;
    }

    public static void toArtifacts( Collection<org.apache.maven.artifact.Artifact> artifacts,
                                    Collection<? extends DependencyNode> nodes, List<String> trail,
                                    DependencyFilter filter )
    {
        for ( DependencyNode node : nodes )
        {
            org.apache.maven.artifact.Artifact artifact = toArtifact( node.getDependency() );

            List<String> nodeTrail = new ArrayList<>( trail.size() + 1 );
            nodeTrail.addAll( trail );

            if ( artifact != null )
            {
                nodeTrail.add( artifact.getId() );

                if ( filter == null || filter.accept( node, Collections.<DependencyNode>emptyList() ) )
                {
                    artifact.setDependencyTrail( nodeTrail );
                    artifacts.add( artifact );
                }
            }

            toArtifacts( artifacts, node.getChildren(), nodeTrail, filter );
        }
    }

    public static Artifact toArtifact( org.apache.maven.artifact.Artifact artifact )
    {
        if ( artifact == null )
        {
            return null;
        }

        String version = artifact.getVersion();
        if ( version == null && artifact.getVersionRange() != null )
        {
            version = artifact.getVersionRange().toString();
        }

        Map<String, String> props = null;
        if ( org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
        {
            String localPath = ( artifact.getFile() != null ) ? artifact.getFile().getPath() : "";
            props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, localPath );
        }

        Artifact result =
            new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(),
                                 artifact.getArtifactHandler().getExtension(), version, props,
                                 newArtifactType( artifact.getType(), artifact.getArtifactHandler() ) );
        result = result.setFile( artifact.getFile() );

        return result;
    }

    public static Dependency toDependency( org.apache.maven.artifact.Artifact artifact,
                                           Collection<org.apache.maven.model.Exclusion> exclusions )
    {
        if ( artifact == null )
        {
            return null;
        }

        Artifact result = toArtifact( artifact );

        List<Exclusion> excl = null;
        if ( exclusions != null )
        {
            excl = new ArrayList<>( exclusions.size() );
            for ( org.apache.maven.model.Exclusion exclusion : exclusions )
            {
                excl.add( toExclusion( exclusion ) );
            }
        }

        return new Dependency( result, artifact.getScope(), artifact.isOptional(), excl );
    }

    public static List<RemoteRepository> toRepos( List<ArtifactRepository> repos )
    {
        if ( repos == null )
        {
            return null;
        }

        List<RemoteRepository> results = new ArrayList<>( repos.size() );
        for ( ArtifactRepository repo : repos )
        {
            results.add( toRepo( repo ) );
        }
        return results;
    }

    public static RemoteRepository toRepo( ArtifactRepository repo )
    {
        RemoteRepository result = null;
        if ( repo != null )
        {
            RemoteRepository.Builder builder =
                new RemoteRepository.Builder( repo.getId(), getLayout( repo ), repo.getUrl() );
            builder.setSnapshotPolicy( toPolicy( repo.getSnapshots() ) );
            builder.setReleasePolicy( toPolicy( repo.getReleases() ) );
            builder.setAuthentication( toAuthentication( repo.getAuthentication() ) );
            builder.setProxy( toProxy( repo.getProxy() ) );
            builder.setMirroredRepositories( toRepos( repo.getMirroredRepositories() ) );
            result = builder.build();
        }
        return result;
    }

    public static String getLayout( ArtifactRepository repo )
    {
        try
        {
            return repo.getLayout().getId();
        }
        catch ( LinkageError e )
        {
            /*
             * NOTE: getId() was added in 3.x and is as such not implemented by plugins compiled against 2.x APIs.
             */
            String className = repo.getLayout().getClass().getSimpleName();
            if ( className.endsWith( "RepositoryLayout" ) )
            {
                String layout = className.substring( 0, className.length() - "RepositoryLayout".length() );
                if ( layout.length() > 0 )
                {
                    layout = Character.toLowerCase( layout.charAt( 0 ) ) + layout.substring( 1 );
                    return layout;
                }
            }
            return "";
        }
    }

    private static RepositoryPolicy toPolicy( ArtifactRepositoryPolicy policy )
    {
        RepositoryPolicy result = null;
        if ( policy != null )
        {
            result = new RepositoryPolicy( policy.isEnabled(), policy.getUpdatePolicy(), policy.getChecksumPolicy() );
        }
        return result;
    }

    private static Authentication toAuthentication( org.apache.maven.artifact.repository.Authentication auth )
    {
        Authentication result = null;
        if ( auth != null )
        {
            AuthenticationBuilder authBuilder = new AuthenticationBuilder();
            authBuilder.addUsername( auth.getUsername() ).addPassword( auth.getPassword() );
            authBuilder.addPrivateKey( auth.getPrivateKey(), auth.getPassphrase() );
            result = authBuilder.build();
        }
        return result;
    }

    private static Proxy toProxy( org.apache.maven.repository.Proxy proxy )
    {
        Proxy result = null;
        if ( proxy != null )
        {
            AuthenticationBuilder authBuilder = new AuthenticationBuilder();
            authBuilder.addUsername( proxy.getUserName() ).addPassword( proxy.getPassword() );
            result = new Proxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), authBuilder.build() );
        }
        return result;
    }

    public static ArtifactHandler newHandler( Artifact artifact )
    {
        String type = artifact.getProperty( ArtifactProperties.TYPE, artifact.getExtension() );
        DefaultArtifactHandler handler = new DefaultArtifactHandler( type );
        handler.setExtension( artifact.getExtension() );
        handler.setLanguage( artifact.getProperty( ArtifactProperties.LANGUAGE, null ) );
        String addedToClasspath = artifact.getProperty( ArtifactProperties.CONSTITUTES_BUILD_PATH, "" );
        handler.setAddedToClasspath( Boolean.parseBoolean( addedToClasspath ) );
        String includesDependencies = artifact.getProperty( ArtifactProperties.INCLUDES_DEPENDENCIES, "" );
        handler.setIncludesDependencies( Boolean.parseBoolean( includesDependencies ) );
        return handler;
    }

    public static ArtifactType newArtifactType( String id, ArtifactHandler handler )
    {
        return new DefaultArtifactType( id, handler.getExtension(), handler.getClassifier(), handler.getLanguage(),
                                        handler.isAddedToClasspath(), handler.isIncludesDependencies() );
    }

    public static Dependency toDependency( org.apache.maven.model.Dependency dependency,
                                           ArtifactTypeRegistry stereotypes )
    {
        ArtifactType stereotype = stereotypes.get( dependency.getType() );
        if ( stereotype == null )
        {
            stereotype = new DefaultArtifactType( dependency.getType() );
        }

        boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0;

        Map<String, String> props = null;
        if ( system )
        {
            props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, dependency.getSystemPath() );
        }

        Artifact artifact =
            new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null,
                                 dependency.getVersion(), props, stereotype );

        List<Exclusion> exclusions = new ArrayList<>( dependency.getExclusions().size() );
        for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() )
        {
            exclusions.add( toExclusion( exclusion ) );
        }

        Dependency result = new Dependency( artifact,
                                            dependency.getScope(),
                                            dependency.getOptional() != null
                                                ? dependency.isOptional()
                                                : null,
                                            exclusions );

        return result;
    }

    private static Exclusion toExclusion( org.apache.maven.model.Exclusion exclusion )
    {
        return new Exclusion( exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*" );
    }

    public static ArtifactTypeRegistry newArtifactTypeRegistry( ArtifactHandlerManager handlerManager )
    {
        return new MavenArtifactTypeRegistry( handlerManager );
    }

    static class MavenArtifactTypeRegistry
        implements ArtifactTypeRegistry
    {

        private final ArtifactHandlerManager handlerManager;

        MavenArtifactTypeRegistry( ArtifactHandlerManager handlerManager )
        {
            this.handlerManager = handlerManager;
        }

        public ArtifactType get( String stereotypeId )
        {
            ArtifactHandler handler = handlerManager.getArtifactHandler( stereotypeId );
            return newArtifactType( stereotypeId, handler );
        }

    }

    public static Collection<Artifact> toArtifacts( Collection<org.apache.maven.artifact.Artifact> artifactsToConvert )
    {
        List<Artifact> artifacts = new ArrayList<>();
        for ( org.apache.maven.artifact.Artifact a : artifactsToConvert )
        {
            artifacts.add( toArtifact( a ) );
        }
        return artifacts;
    }

    public static WorkspaceRepository getWorkspace( RepositorySystemSession session )
    {
        WorkspaceReader reader = session.getWorkspaceReader();
        return ( reader != null ) ? reader.getRepository() : null;
    }

    public static boolean repositoriesEquals( List<RemoteRepository> r1, List<RemoteRepository> r2 )
    {
        if ( r1.size() != r2.size() )
        {
            return false;
        }
    
        for ( Iterator<RemoteRepository> it1 = r1.iterator(), it2 = r2.iterator(); it1.hasNext(); )
        {
            if ( !repositoryEquals( it1.next(), it2.next() ) )
            {
                return false;
            }
        }
    
        return true;
    }

    public static int repositoriesHashCode( List<RemoteRepository> repositories )
    {
        int result = 17;
        for ( RemoteRepository repository : repositories )
        {
            result = 31 * result + repositoryHashCode( repository );
        }
        return result;
    }

    private static int repositoryHashCode( RemoteRepository repository )
    {
        int result = 17;
        Object obj = repository.getUrl();
        result = 31 * result + ( obj != null ? obj.hashCode() : 0 );
        return result;
    }

    private static boolean policyEquals( RepositoryPolicy p1, RepositoryPolicy p2 )
    {
        if ( p1 == p2 )
        {
            return true;
        }
        // update policy doesn't affect contents
        return p1.isEnabled() == p2.isEnabled() && Objects.equals( p1.getChecksumPolicy(), p2.getChecksumPolicy() );
    }

    private static boolean repositoryEquals( RemoteRepository r1, RemoteRepository r2 )
    {
        if ( r1 == r2 )
        {
            return true;
        }
    
        return Objects.equals( r1.getId(), r2.getId() ) && Objects.equals( r1.getUrl(), r2.getUrl() )
            && policyEquals( r1.getPolicy( false ), r2.getPolicy( false ) )
            && policyEquals( r1.getPolicy( true ), r2.getPolicy( true ) );
    }
}
