package org.apache.maven.continuum.notification.wagon;

/*
 * 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 org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.DefaultArtifactRepository;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.continuum.ContinuumException;
import org.apache.maven.continuum.configuration.ConfigurationException;
import org.apache.maven.continuum.configuration.ConfigurationService;
import org.apache.maven.continuum.model.project.BuildDefinition;
import org.apache.maven.continuum.model.project.BuildResult;
import org.apache.maven.continuum.model.project.Project;
import org.apache.maven.continuum.model.project.ProjectNotifier;
import org.apache.maven.continuum.notification.AbstractContinuumNotifier;
import org.apache.maven.continuum.notification.ContinuumNotificationDispatcher;
import org.apache.maven.continuum.notification.MessageContext;
import org.apache.maven.continuum.notification.NotificationException;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.Site;
import org.apache.maven.profiles.DefaultProfileManager;
import org.apache.maven.profiles.ProfileManager;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.settings.MavenSettingsBuilder;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.wagon.CommandExecutionException;
import org.apache.maven.wagon.CommandExecutor;
import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.UnsupportedProtocolException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.authentication.AuthenticationException;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.observers.Debug;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.repository.Repository;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

/**
 * @author <a href="mailto:hisidro@exist.com">Henry Isidro</a>
 * @author <a href="mailto:nramirez@exist.com">Napoleon Esmundo C. Ramirez</a>
 */
@Service("notifier#wagon")
public class WagonContinuumNotifier
    extends AbstractContinuumNotifier
    implements Contextualizable
{
    public static final String BUILD_OUTPUT_FILE_NAME = "buildresult.txt";

    private static final String CONTEXT_MAVEN_PROJECT = "CONTEXT_MAVEN_PROJECT";

    private Logger log = LoggerFactory.getLogger( getClass() );

    @Resource
    private ConfigurationService configurationService;

    @Resource
    private WagonManager wagonManager;

    @Resource
    private MavenProjectBuilder projectBuilder;

    @Resource
    private MavenSettingsBuilder settingsBuilder;

    /**
     * @plexus.configuration
     */
    private String localRepository;

    private Settings settings;

    private ProfileManager profileManager;

    private PlexusContainer container;

    public String getType()
    {
        return "wagon";
    }

    public void sendMessage( String messageId, MessageContext context )
        throws NotificationException
    {
        Project project = context.getProject();

        List<ProjectNotifier> notifiers = context.getNotifiers();

        BuildResult build = context.getBuildResult();

        BuildDefinition buildDefinition = context.getBuildDefinition();

        // ----------------------------------------------------------------------
        // If there wasn't any building done, don't notify
        // ----------------------------------------------------------------------
        if ( build == null )
        {
            return;
        }

        // ----------------------------------------------------------------------
        // Deloy build result to given url 
        // ----------------------------------------------------------------------
        try
        {
            /*
             * acquire the MavenProject associated to the Project in context
             */
            MavenProject mavenProject = getMavenProject( project, buildDefinition );

            if ( messageId.equals( ContinuumNotificationDispatcher.MESSAGE_ID_BUILD_COMPLETE ) )
            {
                for ( ProjectNotifier notifier : notifiers )
                {
                    buildComplete( notifier, build, mavenProject );
                }
            }
        }
        catch ( ContinuumException e )
        {
            throw new NotificationException( "Error while notifiying.", e );
        }
    }

    private void buildComplete( ProjectNotifier notifier, BuildResult build, MavenProject mavenProject )
        throws ContinuumException
    {
        String id;
        String url;

        Map<String, String> configuration = notifier.getConfiguration();

        if ( configuration.containsKey( "url" ) )
        {
            url = configuration.get( "url" );
            id = configuration.get( "id" );
        }
        else
        {
            DistributionManagement distributionManagement = mavenProject.getDistributionManagement();

            if ( distributionManagement == null )
            {
                throw new ContinuumException( "Missing distribution management information in the project." );
            }

            Site site = distributionManagement.getSite();
            if ( site == null )
            {
                throw new ContinuumException(
                    "Missing site information in the distribution management element in the project." );
            }

            url = site.getUrl();
            id = site.getId();
        }

        if ( url == null )
        {
            throw new ContinuumException( "The URL to the site is not defined." );
        }

        Repository repository = new Repository( id, url );

        Wagon wagon;
        try
        {
            wagon = wagonManager.getWagon( repository.getProtocol() );
        }
        catch ( UnsupportedProtocolException e )
        {
            throw new ContinuumException( "Unsupported protocol: '" + repository.getProtocol() + "'", e );
        }

        if ( !wagon.supportsDirectoryCopy() )
        {
            throw new ContinuumException(
                "Wagon protocol '" + repository.getProtocol() + "' doesn't support directory copying" );
        }

        try
        {
            if ( log.isDebugEnabled() )
            {
                Debug debug = new Debug();

                wagon.addSessionListener( debug );
                wagon.addTransferListener( debug );
            }

            ProxyInfo proxyInfo = getProxyInfo( repository );

            if ( proxyInfo != null )
            {
                wagon.connect( repository, getAuthenticationInfo( id ), proxyInfo );
            }
            else
            {
                wagon.connect( repository, getAuthenticationInfo( id ) );
            }

            File buildOutputFile = configurationService.getBuildOutputFile( build.getId(), build.getProject().getId() );

            wagon.put( buildOutputFile, BUILD_OUTPUT_FILE_NAME );

            // TODO: current wagon uses zip which will use the umask on remote host instead of honouring our settings
            //  Force group writeable
            if ( wagon instanceof CommandExecutor )
            {
                CommandExecutor exec = (CommandExecutor) wagon;
                exec.executeCommand( "chmod -Rf g+w " + repository.getBasedir() );
            }
        }
        catch ( ConfigurationException e )
        {
            throw new ContinuumException( "Error uploading build results to deployed site.", e );
        }
        catch ( ResourceDoesNotExistException e )
        {
            throw new ContinuumException( "Error uploading site", e );
        }
        catch ( TransferFailedException e )
        {
            throw new ContinuumException( "Error uploading site", e );
        }
        catch ( AuthorizationException e )
        {
            throw new ContinuumException( "Error uploading site", e );
        }
        catch ( ConnectionException e )
        {
            throw new ContinuumException( "Error uploading site", e );
        }
        catch ( AuthenticationException e )
        {
            throw new ContinuumException( "Error uploading site", e );
        }
        catch ( CommandExecutionException e )
        {
            throw new ContinuumException( "Error uploading site", e );
        }
        finally
        {
            try
            {
                wagon.disconnect();
            }
            catch ( ConnectionException e )
            {
                log.error( "Error disconnecting wagon - ignored", e );
            }
        }
    }

    private MavenProject getMavenProject( Project project, BuildDefinition buildDefinition )
        throws ContinuumException
    {
        File projectWorkingDir =
            new File( configurationService.getWorkingDirectory(), Integer.toString( project.getId() ) );
        File pomFile = new File( projectWorkingDir, buildDefinition.getBuildFile() );

        MavenProject mavenProject;

        try
        {
            mavenProject = projectBuilder.build( pomFile, getLocalRepository(), getProfileManager() );
        }
        catch ( ProjectBuildingException e )
        {
            throw new ContinuumException( "Unable to acquire the MavenProject in " + pomFile.getAbsolutePath(), e );
        }

        return mavenProject;
    }

    private Settings getSettings()
    {
        if ( settings == null )
        {
            try
            {
                settings = settingsBuilder.buildSettings();
            }
            catch ( IOException e )
            {
                log.error( "Failed to get Settings", e );
            }
            catch ( XmlPullParserException e )
            {
                log.error( "Failed to get Settings", e );
            }
        }

        return settings;
    }

    private ArtifactRepository getLocalRepository()
    {
        String repo = localRepository;

        if ( getSettings() != null && !StringUtils.isEmpty( getSettings().getLocalRepository() ) )
        {
            repo = getSettings().getLocalRepository();
        }

        return new DefaultArtifactRepository( "local-repository", "file://" + repo, new DefaultRepositoryLayout() );
    }

    private ProfileManager getProfileManager()
    {
        if ( profileManager == null )
        {
            profileManager = new DefaultProfileManager( container, getSettings() );
        }

        return profileManager;
    }

    public void contextualize( Context context )
        throws ContextException
    {
        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
    }

    private ProxyInfo getProxyInfo( Repository repository )
    {
        Settings settings = getSettings();
        if ( settings.getProxies() != null && !settings.getProxies().isEmpty() )
        {
            for ( Proxy p : (List<Proxy>) settings.getProxies() )
            {
                wagonManager.addProxy( p.getProtocol(), p.getHost(), p.getPort(), p.getUsername(), p.getPassword(),
                                       p.getNonProxyHosts() );
            }
        }
        return wagonManager.getProxy( repository.getProtocol() );
    }

    private AuthenticationInfo getAuthenticationInfo( String repositoryId )
    {
        Settings settings = getSettings();
        Server server = settings.getServer( repositoryId );

        if ( server == null )
        {
            return null;
        }

        wagonManager.addAuthenticationInfo( repositoryId, server.getUsername(), server.getPassword(),
                                            server.getPrivateKey(), server.getPassphrase() );
        return wagonManager.getAuthenticationInfo( repositoryId );
    }
}
