package org.apache.maven.artifact.deployer;

/* ====================================================================
 *   Copyright 2001-2004 The Apache Software Foundation.
 *
 *   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.
 * ====================================================================
 */

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.maven.MavenException;
import org.apache.maven.project.Project;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.maven.wagon.providers.ftp.FtpWagon;
import org.apache.maven.wagon.providers.sshext.ScpExternalWagon;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.repository.Repository;
import org.apache.maven.wagon.repository.RepositoryPermissions;

/**
 * Perform mapping between project's properties and attributes of Wagon Repository class.
 *
 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
 * @version $Id$
 */
public class RepositoryBuilder
{
    private static final Log LOG = LogFactory.getLog( RepositoryBuilder.class );

    public static Repository getRepository( Project project, String id )
        throws MavenException
    {
        String url = (String) project.getContext().getVariable( "maven.repo." + id );
        if ( url == null )
        {
            throw new MavenException( "URL not specified in property: maven.repo." + id );
        }

        Repository repository = new Repository( id, url );

        String dir = (String) project.getContext().getVariable( "maven.repo." + id + ".directory" );
        if ( repository.getBasedir() != null && dir != null )
        {
            dir = dir.replace( '\\', '/' );
            if ( !repository.getBasedir().endsWith( "/" ) && !dir.startsWith( "/" ) )
            {
                dir = "/" + dir;
            }
            dir = repository.getBasedir() + dir;
        }

        repository.setBasedir( dir );
        if ( dir == null )
        {
            throw new MavenException( "Directory not specified in property: maven.repo." + id + ".directory" );
        }

        String port = (String) project.getContext().getVariable( "maven.repo." + id + ".port" );
        if ( port != null )
        {
            try
            {
                repository.setPort( Integer.valueOf( port ).intValue() );
            }
            catch ( NumberFormatException e )
            {
                LOG.warn( "Invalid format for port: " + port );
            }
        }

        String remoteGroup = (String) project.getContext().getVariable( "maven.repo." + id + ".group" );
        String remoteMode = (String) project.getContext().getVariable( "maven.repo." + id + ".mode" );
        String remoteDirectoryMode = (String) project.getContext().getVariable( "maven.repo." + id + ".directory.mode" );

        if ( remoteMode == null )
        {
            remoteMode = "g+w";
        }

        if ( remoteDirectoryMode == null )
        {
            remoteDirectoryMode = remoteMode;
        }

        RepositoryPermissions permissions = new RepositoryPermissions();
        permissions.setDirectoryMode( remoteDirectoryMode );
        permissions.setFileMode( remoteMode );
        permissions.setGroup( remoteGroup );
        repository.setPermissions( permissions );

        return repository;
    }

    public static void configureFtpWagon( Project project, String id, FtpWagon wagon )
    {
/* TODO: implement in FTP wagon
        String passiveModeOn = (String) project.getContext().getVariable( "maven.repo." + id + ".passiveModeOn" );

        String compress = (String) project.getContext().getVariable( "maven.repo." + id + ".compress" );

        if ( passiveModeOn != null )
        {
            if ( "false".equalsIgnoreCase( passiveModeOn ) )
            {
                wagon.setPassiveModeOn( false );
            }
        }
        if ( compress != null )
        {
            try
            {
                wagon.setCompress( new Boolean( compress ).booleanValue() );
            }
            catch ( Exception e )
            {
                throw new MavenException( "maven.repo." + id + ".compress should be a boolean" );
            }
        }
*/
    }

    public static void configureSshExternalWagon( Project project, String id, ScpExternalWagon wagon )
    {
        String scpExe = (String) project.getContext().getVariable( "maven.repo." + id + ".scp.executable" );
        if ( scpExe == null )
        {
            scpExe = (String) project.getContext().getVariable( "maven.scp.executable" );
        }

        if ( scpExe != null )
        {
            wagon.setScpExecutable( scpExe );
        }

        String scpArgs = (String) project.getContext().getVariable( "maven.repo." + id + ".scp.args" );
        if ( scpArgs == null )
        {
            scpArgs = (String) project.getContext().getVariable( "maven.scp.args" );
        }

        if ( scpArgs != null )
        {
            wagon.setScpArgs( scpArgs );
        }

        String sshExe = (String) project.getContext().getVariable( "maven.repo." + id + ".ssh.executable" );
        if ( sshExe == null )
        {
            sshExe = (String) project.getContext().getVariable( "maven.ssh.executable" );
        }

        if ( sshExe != null )
        {
            wagon.setSshExecutable( sshExe );
        }

        String sshArgs = (String) project.getContext().getVariable( "maven.repo." + id + ".ssh.args" );
        if ( sshArgs == null )
        {
            sshArgs = (String) project.getContext().getVariable( "maven.ssh.args" );
        }

        if ( sshArgs != null )
        {
            wagon.setSshArgs( sshArgs );
        }
    }

    public static void getProxyInfo( Project project )
    {
        ProxyInfo proxyInfo = new ProxyInfo();

        String proxyHost = project.getContext().getProxyHost();
        String proxyUser = project.getContext().getProxyUserName();
        String proxyPassword = project.getContext().getProxyPassword();
        String proxyPort = project.getContext().getProxyPort();

        if ( proxyPort != null )
        {
            try
            {
                proxyInfo.setPort( Integer.valueOf( proxyPort ).intValue() );
            }
            catch ( NumberFormatException e )
            {
                LOG.warn( "Invalid format for port: " + proxyPort );
            }
        }

        proxyInfo.setType( "http" );
        proxyInfo.setHost( proxyHost );
        proxyInfo.setNonProxyHosts( (String) project.getContext().getVariable( "maven.proxy.nonProxyHosts" ) );
        proxyInfo.setNtlmDomain( (String) project.getContext().getVariable( "maven.proxy.ntlm.domain" ) );
        proxyInfo.setNtlmHost( (String) project.getContext().getVariable( "maven.proxy.ntlm.host" ) );
        proxyInfo.setUserName( proxyUser );
        proxyInfo.setPassword( proxyPassword );
    }

    public static AuthenticationInfo getAuthenticationInfo( Project project, String id )
    {
        String username = (String) project.getContext().getVariable( "maven.repo." + id + ".username" );
        String password = (String) project.getContext().getVariable( "maven.repo." + id + ".password" );
        String passphrase = (String) project.getContext().getVariable( "maven.repo." + id + ".passphrase" );
        String privateKey = (String) project.getContext().getVariable( "maven.repo." + id + ".privatekey" );

        if ( username == null )
        {
            username = (String) project.getContext().getVariable( "maven.username" );
        }

        AuthenticationInfo authenticationInfo = new AuthenticationInfo();
        authenticationInfo.setUserName( username );
        authenticationInfo.setPassword( password );
        authenticationInfo.setPrivateKey( privateKey );
        authenticationInfo.setPassphrase( passphrase );

        return authenticationInfo;
    }
}
