package org.apache.maven.shared.artifact.filter.resolve.transform;

/*
 * 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.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.maven.shared.artifact.filter.resolve.AbstractFilter;
import org.apache.maven.shared.artifact.filter.resolve.AndFilter;
import org.apache.maven.shared.artifact.filter.resolve.ExclusionsFilter;
import org.apache.maven.shared.artifact.filter.resolve.FilterTransformer;
import org.apache.maven.shared.artifact.filter.resolve.OrFilter;
import org.apache.maven.shared.artifact.filter.resolve.PatternExclusionsFilter;
import org.apache.maven.shared.artifact.filter.resolve.PatternInclusionsFilter;
import org.apache.maven.shared.artifact.filter.resolve.ScopeFilter;
import org.apache.maven.shared.artifact.filter.resolve.TransformableFilter;
import org.sonatype.aether.graph.DependencyFilter;
import org.sonatype.aether.graph.DependencyNode;
import org.sonatype.aether.util.filter.AndDependencyFilter;
import org.sonatype.aether.util.filter.ExclusionsDependencyFilter;
import org.sonatype.aether.util.filter.OrDependencyFilter;
import org.sonatype.aether.util.filter.PatternExclusionsDependencyFilter;
import org.sonatype.aether.util.filter.PatternInclusionsDependencyFilter;
import org.sonatype.aether.util.filter.ScopeDependencyFilter;

/**
 * FilterTransformer implementation for Sonatype Aether
 * 
 * @deprecated update to Maven 3.1.0 or later and replace Sonatype Aether with Eclipse Aether
 * @author Robert Scholte  
 * @since 3.0
 */
@Deprecated
public class SonatypeAetherFilterTransformer
    implements FilterTransformer<DependencyFilter>
{
    /**
     * When using as regular expression, group(1) + group(3) will be the coordinate, 
     * group(2) will be the classifier.
     */
    private static final String GAE_C_V = "(.*:.*:.*):(.+)(:.*)";
    
    @Override
    public AndDependencyFilter transform( AndFilter filter )
    {
        Collection<DependencyFilter> filters = new ArrayList<>( filter.getFilters().size() );
        for ( TransformableFilter dependencyFilter : filter.getFilters() )
        {
            filters.add( dependencyFilter.transform( this ) );
        }
        return new AndDependencyFilter( filters );
    }

    @Override
    public ExclusionsDependencyFilter transform( ExclusionsFilter filter )
    {
        return new ExclusionsDependencyFilter( filter.getExcludes() );
    }
    
    @Override
    public OrDependencyFilter transform( OrFilter filter )
    {
        Collection<DependencyFilter> filters = new ArrayList<>( filter.getFilters().size() );
        for ( TransformableFilter dependencyFilter : filter.getFilters() )
        {
            filters.add( dependencyFilter.transform( this ) );
        }
        return new OrDependencyFilter( filters );
    }
    
    @Override
    public ScopeDependencyFilter transform( ScopeFilter filter )
    {
        return new ScopeDependencyFilter( filter.getIncluded(), filter.getExcluded() );
    }
    
    @Override
    public DependencyFilter transform( PatternExclusionsFilter filter )
    {
        return new PatternExclusionsDependencyFilter( filter.getExcludes() );
    }
    
    @Override
    public DependencyFilter transform( PatternInclusionsFilter filter )
    {
     // if any include contains a classifier:
        // split all includes and make it an or-filter for every include
        // for the classifier, add an and-filter with a classifierfilter and patterninclusionfilter
        
        for ( String include : filter.getIncludes() )
        {
            if ( include.matches( GAE_C_V ) )
            {
                return newAdvancedPatternInclusionFilter( filter.getIncludes() );
            }
        }
        
        return new PatternInclusionsDependencyFilter( filter.getIncludes() );
    }
    
    @Override
    public DependencyFilter transform( final AbstractFilter filter )
    {
        return new DependencyFilter()
        {
            @Override
            public boolean accept( DependencyNode node, List<DependencyNode> parents )
            {
                return filter.accept( new SonatypeAetherNode( node ), null );
            }
        };
    }
    
    private DependencyFilter newAdvancedPatternInclusionFilter( Collection<String> includes )
    {
        List<DependencyFilter> filters = new ArrayList<>( includes.size() );

        Pattern pattern = Pattern.compile( GAE_C_V );
        for ( String include : includes )
        {
            Matcher matcher = pattern.matcher( include );
            if ( matcher.matches() )
            {
                DependencyFilter patternFilter =
                    new PatternInclusionsDependencyFilter( matcher.group( 1 ) + matcher.group( 3 ) );

                final String classifier = matcher.group( 2 );
                
                DependencyFilter classifierFilter = new DependencyFilter()
                {
                    @Override
                    public boolean accept( DependencyNode node, List<DependencyNode> parents )
                    {
                        String nodeClassifier = node.getDependency().getArtifact().getClassifier();
                        
                        if ( nodeClassifier == null )
                        {
                            return false;
                        }
                        else 
                        {
                            return "*".equals( classifier ) || nodeClassifier.matches( classifier );
                        }
                    }
                };

                filters.add( new AndDependencyFilter( patternFilter, classifierFilter ) );
            }
            else
            {
                filters.add( new PatternInclusionsDependencyFilter( include ) );
            }
        }
        return new OrDependencyFilter( filters );
    }
}
