/*-
 * Copyright (c) 2012-2013 Red Hat, Inc.
 *
 * Licensed 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.fedoraproject.maven.resolver;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;

import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.StringUtils;
import org.fedoraproject.maven.config.Configurator;
import org.fedoraproject.maven.config.RepositoryConfigurator;
import org.fedoraproject.maven.config.ResolverSettings;
import org.fedoraproject.maven.model.Artifact;
import org.fedoraproject.maven.repository.Repository;
import org.fedoraproject.maven.utils.AtomicFileCounter;
import org.fedoraproject.maven.utils.LoggingUtils;

/**
 * Default implementation of XMvn {@code Resolver} interface.
 * 
 * @author Mikolaj Izdebski
 */
@Component( role = Resolver.class )
public class DefaultResolver
    extends AbstractResolver
{
    @Requirement
    private Logger logger;

    @Requirement
    private Configurator configurator;

    @Requirement
    private RepositoryConfigurator repositoryConfigurator;

    private Repository bisectRepo;

    private AtomicFileCounter bisectCounter;

    private boolean initialized;

    private final Collection<Resolver> resolvers = new LinkedList<>();

    private void initializeBisect()
    {
        try
        {
            String bisectCounterPath = System.getProperty( "xmvn.bisect.counter" );
            if ( StringUtils.isEmpty( bisectCounterPath ) )
            {
                logger.debug( "Bisection build is not enabled" );
                return;
            }
            bisectCounter = new AtomicFileCounter( bisectCounterPath );

            bisectRepo = repositoryConfigurator.configureRepository( "bisect" );

            logger.info( "Enabled XMvn bisection build" );
        }
        catch ( IOException e )
        {
            logger.fatalError( "Unable to initialize XMvn bisection build", e );
            throw new RuntimeException( e );
        }
    }

    private void initialize()
    {
        initializeBisect();

        ResolverSettings settings = configurator.getConfiguration().getResolverSettings();
        LoggingUtils.setLoggerThreshold( logger, settings.isDebug() );

        // FIXME: this needs to be implemented
        // resolvers.add( new LocalResolver( settings ) );

        for ( String prefix : settings.getPrefixes() )
        {
            File root = new File( prefix );
            if ( root.isDirectory() )
            {
                resolvers.add( new JavaHomeResolver( root, settings, logger ) );
                Resolver resolver = new SystemResolver( root, settings, logger );
                resolvers.add( new CachingResolver( resolver, logger ) );
            }
        }

        initialized = true;
    }

    private boolean resolveFromBisectRepo()
    {
        if ( bisectCounter == null || bisectRepo == null )
            return false;

        try
        {
            return bisectCounter.tryDecrement() > 0;
        }
        catch ( IOException e )
        {
            logger.fatalError( "Failed to decrement bisection counter", e );
            throw new RuntimeException( e );
        }
    }

    @Override
    public ResolutionResult resolve( ResolutionRequest request )
    {
        if ( !initialized )
            initialize();

        Artifact artifact = request.getArtifact();

        if ( resolveFromBisectRepo() )
        {
            logger.debug( "Resolving artifact " + artifact + " from bisection repository." );
            File artifactFile = bisectRepo.getPrimaryArtifactPath( artifact ).toFile();
            return new DefaultResolutionResult( artifactFile, bisectRepo );
        }

        logger.debug( "Trying to resolve artifact " + artifact );

        for ( Resolver resolver : resolvers )
        {
            ResolutionResult result = resolver.resolve( request );
            if ( result != null )
                return result;
        }

        logger.debug( "Unresolved artifact " + artifact );
        return new DefaultResolutionResult();
    }
}

@@ -688,24 +688,52 @@
 OException;%0A
+import java.util.ArrayList;%0A
 import java.
@@ -777,16 +777,39 @@
 kedList;
+%0Aimport java.util.List;
 %0A%0Aimport
@@ -1804,16 +1804,87 @@
 tRepo;%0A%0A
+    private Repository systemRepo;%0A%0A    private DependencyMap depmap;%0A%0A
     priv
@@ -3093,24 +3093,79 @@
 tings ) );%0A%0A
+        List%3CString%3E metadataDirs = new ArrayList%3C%3E();%0A
         for 
@@ -3333,151 +3333,134 @@
     
-resolvers.add( new JavaHomeResolver( root, settings, logger ) );%0A                Resolver resolver = new SystemResolver( root, settings, logger
+for ( String dir : settings.getMetadataRepositories() )%0A                    metadataDirs.add( new File( root, dir ).toString()
  );%0A
@@ -3467,24 +3467,30 @@
         
+    %7D%0A
         
 resolver
@@ -3485,62 +3485,53 @@
     
-resolvers.add( new CachingResolver( resolver,
+%7D%0A%0A        depmap = new DependencyMap(
  logger
- )
  );%0A
@@ -3534,39 +3534,118 @@
  );%0A        
-    %7D%0A        %7D
+DepmapReader reader = new DepmapReader();%0A        reader.readMappings( depmap, metadataDirs );
 %0A%0A        in

Read depmaps in DefaultResolver