/*******************************************************************************
 * Copyright (c) 2010, 2014 Sonatype, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Sonatype, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.aether.ant;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.maven.model.Model;
import org.apache.maven.model.building.DefaultModelBuilderFactory;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.building.FileModelSource;
import org.apache.maven.model.building.ModelBuilder;
import org.apache.maven.model.building.ModelBuildingException;
import org.apache.maven.model.building.ModelBuildingRequest;
import org.apache.maven.model.resolution.ModelResolver;
import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.building.DefaultSettingsBuilderFactory;
import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuilder;
import org.apache.maven.settings.building.SettingsBuildingException;
import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
import org.apache.maven.settings.crypto.SettingsDecrypter;
import org.apache.maven.settings.crypto.SettingsDecryptionResult;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.condition.Os;
import org.apache.tools.ant.types.Reference;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.aether.ConfigurationProperties;
import org.eclipse.aether.DefaultRepositoryCache;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.ant.listeners.AntRepositoryListener;
import org.eclipse.aether.ant.listeners.AntTransferListener;
import org.eclipse.aether.ant.types.Authentication;
import org.eclipse.aether.ant.types.Dependencies;
import org.eclipse.aether.ant.types.Dependency;
import org.eclipse.aether.ant.types.Exclusion;
import org.eclipse.aether.ant.types.LocalRepository;
import org.eclipse.aether.ant.types.Mirror;
import org.eclipse.aether.ant.types.Pom;
import org.eclipse.aether.ant.types.Proxy;
import org.eclipse.aether.ant.types.RemoteRepositories;
import org.eclipse.aether.ant.types.RemoteRepository;
import org.eclipse.aether.ant.util.AetherUtils;
import org.eclipse.aether.ant.util.ConverterUtils;
import org.eclipse.aether.ant.util.SettingsUtils;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.collection.CollectResult;
import org.eclipse.aether.collection.DependencyCollectionException;
import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
import org.eclipse.aether.impl.DefaultServiceLocator;
import org.eclipse.aether.impl.RemoteRepositoryManager;
import org.eclipse.aether.repository.AuthenticationSelector;
import org.eclipse.aether.repository.LocalRepositoryManager;
import org.eclipse.aether.repository.MirrorSelector;
import org.eclipse.aether.repository.ProxySelector;
import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
import org.eclipse.aether.spi.connector.transport.TransporterFactory;
import org.eclipse.aether.spi.log.Logger;
import org.eclipse.aether.transport.classpath.ClasspathTransporterFactory;
import org.eclipse.aether.transport.file.FileTransporterFactory;
import org.eclipse.aether.transport.http.HttpTransporterFactory;
import org.eclipse.aether.util.repository.AuthenticationBuilder;
import org.eclipse.aether.util.repository.ConservativeAuthenticationSelector;
import org.eclipse.aether.util.repository.DefaultAuthenticationSelector;
import org.eclipse.aether.util.repository.DefaultMirrorSelector;
import org.eclipse.aether.util.repository.DefaultProxySelector;

/**
 */
public class AntRepoSys
{

    private static boolean OS_WINDOWS = Os.isFamily( "windows" );

    private static final ModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();

    private static final SettingsBuilder settingsBuilder = new DefaultSettingsBuilderFactory().newInstance();

    private static final SettingsDecrypter settingsDecrypter = new AntSettingsDecryptorFactory().newInstance();

    private final Project project;

    private final DefaultServiceLocator locator;

    private RepositorySystem repoSys;

    private RemoteRepositoryManager remoteRepoMan;

    private File userSettings;

    private File globalSettings;

    private Settings settings;

    private final List<Mirror> mirrors = new CopyOnWriteArrayList<Mirror>();

    private final List<Proxy> proxies = new CopyOnWriteArrayList<Proxy>();

    private final List<Authentication> authentications = new CopyOnWriteArrayList<Authentication>();

    private LocalRepository localRepository;

    private Pom defaultPom;

    private static <T> boolean eq( T o1, T o2 )
    {
        return ( o1 == null ) ? o2 == null : o1.equals( o2 );
    }

    public static synchronized AntRepoSys getInstance( Project project )
    {
        Object obj = project.getReference( Names.ID );
        if ( obj instanceof AntRepoSys )
        {
            return (AntRepoSys) obj;
        }
        AntRepoSys instance = new AntRepoSys( project );
        project.addReference( Names.ID, instance );
        instance.initDefaults();
        return instance;
    }

    private AntRepoSys( Project project )
    {
        this.project = project;

        locator = MavenRepositorySystemUtils.newServiceLocator();
        locator.setErrorHandler( new AntServiceLocatorErrorHandler( project ) );
        locator.setServices( Logger.class, new AntLogger( project ) );
        locator.setServices( ModelBuilder.class, modelBuilder );
        locator.addService( RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class );
        locator.addService( TransporterFactory.class, FileTransporterFactory.class );
        locator.addService( TransporterFactory.class, HttpTransporterFactory.class );
        locator.addService( TransporterFactory.class, ClasspathTransporterFactory.class );
    }

    private void initDefaults()
    {
        RemoteRepository repo = new RemoteRepository();
        repo.setProject( project );
        repo.setId( "central" );
        repo.setUrl( "http://repo1.maven.org/maven2/" );
        project.addReference( Names.ID_CENTRAL, repo );

        repo = new RemoteRepository();
        repo.setProject( project );
        repo.setRefid( new Reference( project, Names.ID_CENTRAL ) );
        RemoteRepositories repos = new RemoteRepositories();
        repos.setProject( project );
        repos.addRemoterepo( repo );
        project.addReference( Names.ID_DEFAULT_REPOS, repos );
    }

    public synchronized RepositorySystem getSystem()
    {
        if ( repoSys == null )
        {
            repoSys = locator.getService( RepositorySystem.class );
            if ( repoSys == null )
            {
                throw new BuildException( "The repository system could not be initialized" );
            }
        }
        return repoSys;
    }

    private synchronized RemoteRepositoryManager getRemoteRepoMan()
    {
        if ( remoteRepoMan == null )
        {
            remoteRepoMan = locator.getService( RemoteRepositoryManager.class );
            if ( remoteRepoMan == null )
            {
                throw new BuildException( "The repository system could not be initialized" );
            }
        }
        return remoteRepoMan;
    }

    public RepositorySystemSession getSession( Task task, LocalRepository localRepo )
    {
        DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();

        Map<Object, Object> configProps = new LinkedHashMap<Object, Object>();
        configProps.put( ConfigurationProperties.USER_AGENT, getUserAgent() );
        configProps.putAll( (Map<?, ?>) project.getProperties() );
        processServerConfiguration( configProps );
        session.setConfigProperties( configProps );

        session.setOffline( isOffline() );
        session.setUserProperties( project.getUserProperties() );

        session.setProxySelector( getProxySelector() );
        session.setMirrorSelector( getMirrorSelector() );
        session.setAuthenticationSelector( getAuthSelector() );

        session.setCache( new DefaultRepositoryCache() );

        session.setRepositoryListener( new AntRepositoryListener( task ) );
        session.setTransferListener( new AntTransferListener( task ) );

        session.setLocalRepositoryManager( getLocalRepoMan( session, localRepo ) );

        session.setWorkspaceReader( ProjectWorkspaceReader.getInstance() );

        return session;
    }

    private String getUserAgent()
    {
        StringBuilder buffer = new StringBuilder( 128 );

        buffer.append( "Apache-Ant/" ).append( project.getProperty( "ant.version" ) );
        buffer.append( " (" );
        buffer.append( "Java " ).append( System.getProperty( "java.version" ) );
        buffer.append( "; " );
        buffer.append( System.getProperty( "os.name" ) ).append( " " ).append( System.getProperty( "os.version" ) );
        buffer.append( ")" );
        buffer.append( " Aether" );

        return buffer.toString();
    }

    private boolean isOffline()
    {
        String prop = project.getProperty( Names.PROPERTY_OFFLINE );
        if ( prop != null )
        {
            return Boolean.parseBoolean( prop );
        }
        return getSettings().isOffline();
    }

    private void processServerConfiguration( Map<Object, Object> configProps )
    {
        Settings settings = getSettings();
        for ( Server server : settings.getServers() )
        {
            if ( server.getConfiguration() != null )
            {
                Xpp3Dom dom = (Xpp3Dom) server.getConfiguration();
                for ( int i = dom.getChildCount() - 1; i >= 0; i-- )
                {
                    Xpp3Dom child = dom.getChild( i );
                    if ( "wagonProvider".equals( child.getName() ) )
                    {
                        dom.removeChild( i );
                    }
                    else if ( "httpHeaders".equals( child.getName() ) )
                    {
                        configProps.put( ConfigurationProperties.HTTP_HEADERS + "." + server.getId(),
                                         getHttpHeaders( child ) );
                    }
                }

                configProps.put( "aether.connector.wagon.config." + server.getId(), dom );
            }

            configProps.put( "aether.connector.perms.fileMode." + server.getId(), server.getFilePermissions() );
            configProps.put( "aether.connector.perms.dirMode." + server.getId(), server.getDirectoryPermissions() );
        }
    }

    private Map<String, String> getHttpHeaders( Xpp3Dom dom )
    {
        Map<String, String> headers = new HashMap<String, String>();
        for ( int i = 0; i < dom.getChildCount(); i++ )
        {
            Xpp3Dom child = dom.getChild( i );
            Xpp3Dom name = child.getChild( "name" );
            Xpp3Dom value = child.getChild( "value" );
            if ( name != null && name.getValue() != null )
            {
                headers.put( name.getValue(), ( value != null ) ? value.getValue() : null );
            }
        }
        return Collections.unmodifiableMap( headers );
    }

    private File getDefaultLocalRepoDir()
    {
        String dir = project.getProperty( "maven.repo.local" );
        if ( dir != null )
        {
            return project.resolveFile( dir );
        }

        Settings settings = getSettings();
        if ( settings.getLocalRepository() != null )
        {
            return new File( settings.getLocalRepository() );
        }

        return new File( new File( project.getProperty( "user.home" ), ".m2" ), "repository" );
    }

    private LocalRepositoryManager getLocalRepoMan( RepositorySystemSession session, LocalRepository localRepo )
    {
        if ( localRepo == null )
        {
            localRepo = localRepository;
        }

        File repoDir;
        if ( localRepo != null && localRepo.getDir() != null )
        {
            repoDir = localRepo.getDir();
        }
        else
        {
            repoDir = getDefaultLocalRepoDir();
        }

        org.eclipse.aether.repository.LocalRepository repo =
            new org.eclipse.aether.repository.LocalRepository( repoDir );

        return getSystem().newLocalRepositoryManager( session, repo );
    }

    private synchronized Settings getSettings()
    {
        if ( settings == null )
        {
            DefaultSettingsBuildingRequest request = new DefaultSettingsBuildingRequest();
            request.setUserSettingsFile( getUserSettings() );
            request.setGlobalSettingsFile( getGlobalSettings() );
            request.setSystemProperties( getSystemProperties() );
            request.setUserProperties( getUserProperties() );

            try
            {
                settings = settingsBuilder.build( request ).getEffectiveSettings();
            }
            catch ( SettingsBuildingException e )
            {
                project.log( "Could not process settings.xml: " + e.getMessage(), e, Project.MSG_WARN );
            }

            SettingsDecryptionResult result =
                settingsDecrypter.decrypt( new DefaultSettingsDecryptionRequest( settings ) );
            settings.setServers( result.getServers() );
            settings.setProxies( result.getProxies() );
        }
        return settings;
    }

    private ProxySelector getProxySelector()
    {
        DefaultProxySelector selector = new DefaultProxySelector();

        for ( Proxy proxy : proxies )
        {
            selector.add( ConverterUtils.toProxy( proxy ), proxy.getNonProxyHosts() );
        }

        Settings settings = getSettings();
        for ( org.apache.maven.settings.Proxy proxy : settings.getProxies() )
        {
            AuthenticationBuilder auth = new AuthenticationBuilder();
            auth.addUsername( proxy.getUsername() ).addPassword( proxy.getPassword() );
            selector.add( new org.eclipse.aether.repository.Proxy( proxy.getProtocol(), proxy.getHost(),
                                                                   proxy.getPort(), auth.build() ),
                          proxy.getNonProxyHosts() );
        }

        return selector;
    }

    private MirrorSelector getMirrorSelector()
    {
        DefaultMirrorSelector selector = new DefaultMirrorSelector();

        for ( Mirror mirror : mirrors )
        {
            selector.add( mirror.getId(), mirror.getUrl(), mirror.getType(), false, mirror.getMirrorOf(), null );
        }

        Settings settings = getSettings();
        for ( org.apache.maven.settings.Mirror mirror : settings.getMirrors() )
        {
            selector.add( String.valueOf( mirror.getId() ), mirror.getUrl(), mirror.getLayout(), false,
                          mirror.getMirrorOf(), mirror.getMirrorOfLayouts() );
        }

        return selector;
    }

    private AuthenticationSelector getAuthSelector()
    {
        DefaultAuthenticationSelector selector = new DefaultAuthenticationSelector();

        Collection<String> ids = new HashSet<String>();
        for ( Authentication auth : authentications )
        {
            List<String> servers = auth.getServers();
            if ( !servers.isEmpty() )
            {
                org.eclipse.aether.repository.Authentication a = ConverterUtils.toAuthentication( auth );
                for ( String server : servers )
                {
                    if ( ids.add( server ) )
                    {
                        selector.add( server, a );
                    }
                }
            }
        }

        Settings settings = getSettings();
        for ( Server server : settings.getServers() )
        {
            AuthenticationBuilder auth = new AuthenticationBuilder();
            auth.addUsername( server.getUsername() ).addPassword( server.getPassword() );
            auth.addPrivateKey( server.getPrivateKey(), server.getPassphrase() );
            selector.add( server.getId(), auth.build() );
        }

        return new ConservativeAuthenticationSelector( selector );
    }

    public synchronized void setUserSettings( File file )
    {
        if ( !eq( this.userSettings, file ) )
        {
            settings = null;
        }
        this.userSettings = file;
    }

    /* UT */File getUserSettings()
    {
        if ( userSettings == null )
        {
            userSettings = AetherUtils.findUserSettings( project );
        }
        return userSettings;
    }

    public void setGlobalSettings( File file )
    {
        if ( !eq( this.globalSettings, file ) )
        {
            settings = null;
        }
        this.globalSettings = file;
    }

    /* UT */File getGlobalSettings()
    {
        if ( globalSettings == null )
        {
            globalSettings = AetherUtils.findGlobalSettings( project );
        }
        return globalSettings;
    }

    public void addProxy( Proxy proxy )
    {
        proxies.add( proxy );
    }

    public void addMirror( Mirror mirror )
    {
        mirrors.add( mirror );
    }

    public void addAuthentication( Authentication authentication )
    {
        authentications.add( authentication );
    }

    public void setLocalRepository( LocalRepository localRepository )
    {
        this.localRepository = localRepository;
    }

    public Model loadModel( Task task, File pomFile, boolean local, RemoteRepositories remoteRepositories )
    {
        RepositorySystemSession session = getSession( task, null );

        remoteRepositories =
            remoteRepositories == null ? AetherUtils.getDefaultRepositories( project ) : remoteRepositories;

        List<org.eclipse.aether.repository.RemoteRepository> repositories =
            ConverterUtils.toRepositories( task.getProject(), session, remoteRepositories, getRemoteRepoMan() );

        ModelResolver modelResolver =
            new AntModelResolver( session, "project", getSystem(), getRemoteRepoMan(), repositories );

        Settings settings = getSettings();

        try
        {
            DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
            request.setLocationTracking( true );
            request.setProcessPlugins( false );
            if ( local )
            {
                request.setPomFile( pomFile );
                request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_STRICT );
            }
            else
            {
                request.setModelSource( new FileModelSource( pomFile ) );
                request.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL );
            }
            request.setSystemProperties( getSystemProperties() );
            request.setUserProperties( getUserProperties() );
            request.setProfiles( SettingsUtils.convert( settings.getProfiles() ) );
            request.setActiveProfileIds( settings.getActiveProfiles() );
            request.setModelResolver( modelResolver );
            return modelBuilder.build( request ).getEffectiveModel();
        }
        catch ( ModelBuildingException e )
        {
            throw new BuildException( "Could not load POM " + pomFile + ": " + e.getMessage(), e );
        }
    }

    private Properties getSystemProperties()
    {
        Properties props = new Properties();
        getEnvProperties( props );
        props.putAll( System.getProperties() );
        ConverterUtils.addProperties( props, project.getProperties() );
        return props;
    }

    private Properties getEnvProperties( Properties props )
    {
        if ( props == null )
        {
            props = new Properties();
        }
        boolean envCaseInsensitive = OS_WINDOWS;
        for ( Map.Entry<String, String> entry : System.getenv().entrySet() )
        {
            String key = entry.getKey();
            if ( envCaseInsensitive )
            {
                key = key.toUpperCase( Locale.ENGLISH );
            }
            key = "env." + key;
            props.put( key, entry.getValue() );
        }
        return props;
    }

    private Properties getUserProperties()
    {
        return ConverterUtils.addProperties( null, project.getUserProperties() );
    }

    /**
     * Sets the default POM.
     */
    public void setDefaultPom( Pom pom )
    {
        this.defaultPom = pom;
    }

    /**
     * Returns the current default POM.
     */
    public Pom getDefaultPom()
    {
        return defaultPom;
    }

    public CollectResult collectDependencies( Task task, Dependencies dependencies, LocalRepository localRepository,
                                              RemoteRepositories remoteRepositories )
    {
        RepositorySystemSession session = getSession( task, localRepository );

        remoteRepositories =
            remoteRepositories == null ? AetherUtils.getDefaultRepositories( project ) : remoteRepositories;

        List<org.eclipse.aether.repository.RemoteRepository> repos =
            ConverterUtils.toRepositories( project, session, remoteRepositories, getRemoteRepoMan() );

        CollectRequest collectRequest = new CollectRequest();
        collectRequest.setRequestContext( "project" );

        for ( org.eclipse.aether.repository.RemoteRepository repo : repos )
        {
            task.getProject().log( "Using remote repository " + repo, Project.MSG_VERBOSE );
            collectRequest.addRepository( repo );
        }

        if ( dependencies != null )
        {
            List<Exclusion> globalExclusions = dependencies.getExclusions();
            Collection<String> ids = new HashSet<String>();

            for ( Dependency dep : dependencies.getDependencies() )
            {
                ids.add( dep.getVersionlessKey() );
                collectRequest.addDependency( ConverterUtils.toDependency( dep, globalExclusions, session ) );
            }

            if ( dependencies.getPom() != null )
            {
                Model model = dependencies.getPom().getModel( task );
                for ( org.apache.maven.model.Dependency dep : model.getDependencies() )
                {
                    Dependency dependency = new Dependency();
                    dependency.setArtifactId( dep.getArtifactId() );
                    dependency.setClassifier( dep.getClassifier() );
                    dependency.setGroupId( dep.getGroupId() );
                    dependency.setScope( dep.getScope() );
                    dependency.setType( dep.getType() );
                    dependency.setVersion( dep.getVersion() );
                    if ( ids.contains( dependency.getVersionlessKey() ) )
                    {
                        project.log( "Ignoring dependency " + dependency.getVersionlessKey() + " from " + model.getId()
                            + ", already declared locally", Project.MSG_VERBOSE );
                        continue;
                    }
                    if ( dep.getSystemPath() != null && dep.getSystemPath().length() > 0 )
                    {
                        dependency.setSystemPath( task.getProject().resolveFile( dep.getSystemPath() ) );
                    }
                    for ( org.apache.maven.model.Exclusion exc : dep.getExclusions() )
                    {
                        Exclusion exclusion = new Exclusion();
                        exclusion.setGroupId( exc.getGroupId() );
                        exclusion.setArtifactId( exc.getArtifactId() );
                        exclusion.setClassifier( "*" );
                        exclusion.setExtension( "*" );
                        dependency.addExclusion( exclusion );
                    }
                    collectRequest.addDependency( ConverterUtils.toDependency( dependency, globalExclusions, session ) );
                }
            }

            if ( dependencies.getFile() != null )
            {
                List<Dependency> deps = readDependencies( dependencies.getFile() );
                for ( Dependency dependency : deps )
                {
                    if ( ids.contains( dependency.getVersionlessKey() ) )
                    {
                        project.log( "Ignoring dependency " + dependency.getVersionlessKey() + " from "
                                         + dependencies.getFile() + ", already declared locally", Project.MSG_VERBOSE );
                        continue;
                    }
                    collectRequest.addDependency( ConverterUtils.toDependency( dependency, globalExclusions, session ) );
                }
            }
        }

        task.getProject().log( "Collecting dependencies", Project.MSG_VERBOSE );

        CollectResult result;
        try
        {
            result = getSystem().collectDependencies( session, collectRequest );
        }
        catch ( DependencyCollectionException e )
        {
            throw new BuildException( "Could not collect dependencies: " + e.getMessage(), e );
        }

        return result;
    }

    private List<Dependency> readDependencies( File file )
    {
        List<Dependency> dependencies = new ArrayList<Dependency>();
        try
        {
            BufferedReader reader = new BufferedReader( new InputStreamReader( new FileInputStream( file ), "UTF-8" ) );
            try
            {
                for ( String line = reader.readLine(); line != null; line = reader.readLine() )
                {
                    int comment = line.indexOf( '#' );
                    if ( comment >= 0 )
                    {
                        line = line.substring( 0, comment );
                    }
                    line = line.trim();
                    if ( line.length() <= 0 )
                    {
                        continue;
                    }
                    Dependency dependency = new Dependency();
                    dependency.setCoords( line );
                    dependencies.add( dependency );
                }
            }
            finally
            {
                reader.close();
            }
        }
        catch ( IOException e )
        {
            throw new BuildException( "Cannot read " + file, e );
        }
        return dependencies;
    }

}
