package org.apache.maven.integrationtests;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.it.IntegrationTestRunner;

public class MavenITmng3652UserAgentHeader
    extends AbstractMavenIntegrationTestCase
{
    public MavenITmng3652UserAgentHeader()
        throws InvalidVersionSpecificationException
    {
        // TODO: fix support for this in 2.1-SNAPSHOT
        // 2.0.10+
        //super( "(2.0.9,)" );
        super( "(2.0.9,2.1-SNAPSHOT)" );
    }

    /**
     * Test that the user agent header is configured in the wagon manager.
     */
    public void testmng3652()
        throws Exception
    {
        File testDir = extractTestResources( getClass(), "/mng-3652-user-agent" );
        File pluginDir = new File( testDir, "test-plugin" );
        File projectDir = new File( testDir, "test-project" );

        IntegrationTestRunner itr = new IntegrationTestRunner( pluginDir.getAbsolutePath() );
        itr.invoke( "install" );
        itr.verifyErrorFreeLog();
        itr.resetStreams();

        int port = ( Math.abs( new Random().nextInt() ) % 2048 ) + 1024;

        Server s = new Server( port );
        Thread t = new Thread( s );
        t.setDaemon( true );
        t.start();
        
        itr = new IntegrationTestRunner( projectDir.getAbsolutePath() );
        
        List cliOptions = new ArrayList();
        cliOptions.add( "-DtestPort=" + port );
        
        itr.executeGoal( "validate", cliOptions );
        itr.verifyErrorFreeLog();
        itr.resetStreams();
        
        String userAgent = s.userAgent;
        assertNotNull( userAgent );
        
        File touchFile = new File( projectDir, "target/touch.txt" );
        assertTrue( touchFile.exists() );
        
        List lines = itr.loadFile( touchFile, false );

        // NOTE: system property for maven.version may not exist if you use -Dtest
        // surefire parameter to run this single test. Therefore, the plugin writes
        // the maven version into the check file.
        String mavenVersion = ((String) lines.get( 0 )).substring( 0, 3 );
        String javaVersion = (String) lines.get( 1 );
        String os = (String) lines.get( 2 ) + " " + (String) lines.get( 3 );
        String artifactVersion = (String) lines.get( 4 );

        assertEquals( "Comparing User-Agent '" + userAgent + "'", "Apache-Maven/" + mavenVersion + " (Java " + javaVersion + "; " + os + ")" + " maven-artifact/" + artifactVersion, userAgent );

        // test webdav
        cliOptions = new ArrayList();
        cliOptions.add( "-DtestPort=" + port );
        cliOptions.add( "-DtestProtocol=dav:http" );
        
        itr.executeGoal( "validate", cliOptions );
        itr.verifyErrorFreeLog();
        itr.resetStreams();
        
        userAgent = s.userAgent;
        assertNotNull( userAgent );
        assertEquals( "Comparing User-Agent '" + userAgent + "'", "Apache-Maven/" + mavenVersion + " (Java " + javaVersion + "; " + os + ")" + " maven-artifact/" + artifactVersion, userAgent );

        // test settings with no config

        cliOptions = new ArrayList();
        cliOptions.add( "-DtestPort=" + port );
        cliOptions.add( "--settings" );
        cliOptions.add( "settings-no-config.xml" );
        
        itr.executeGoal( "validate", cliOptions );
        itr.verifyErrorFreeLog();
        itr.resetStreams();
        
        userAgent = s.userAgent;
        assertNotNull( userAgent );
        assertEquals( "Comparing User-Agent '" + userAgent + "'", "Apache-Maven/" + mavenVersion + " (Java " + javaVersion + "; " + os + ")" + " maven-artifact/" + artifactVersion, userAgent );

        // test settings with config

        cliOptions = new ArrayList();
        cliOptions.add( "-DtestPort=" + port );
        cliOptions.add( "--settings" );
        cliOptions.add( "settings.xml" );
        
        itr.executeGoal( "validate", cliOptions );
        itr.verifyErrorFreeLog();
        itr.resetStreams();
        
        userAgent = s.userAgent;
        assertNotNull( userAgent );
        assertEquals( "Maven Fu", userAgent );        

        t.interrupt();
    }

    private static final class Server
        implements Runnable
    {
        
        private final int port;
        
        private String userAgent;

        private Server( int port )
        {
            this.port = port;
        }

        public void run()
        {
            ServerSocket ssock = null;
            try
            {
                try
                {
                    ssock = new ServerSocket( port );
                    ssock.setSoTimeout( 2000 );
                }
                catch ( IOException e )
                {
                    Logger.getLogger( Server.class.getName() ).log( Level.SEVERE, "", e );
                    return;
                }

                while ( !Thread.currentThread().isInterrupted() )
                {
                    Socket sock = null;
                    BufferedReader r = null;
                    try
                    {
                        try
                        {
                            sock = ssock.accept();
                        }
                        catch ( SocketTimeoutException e )
                        {
                            continue;
                        }

                        r = new BufferedReader( new InputStreamReader( sock.getInputStream() ) );

                        String line = null;
                        int count = 0;
                        while ( ( line = r.readLine() ) != null )
                        {
                            Logger.getLogger( Server.class.getName() ).fine( line );
                            if ( line.startsWith( "User-Agent:" ) )
                            {
                                userAgent = line.replaceAll( "User-Agent:\\s+", "" );
                                
                                break;
                            }
                            count++;
                        }
                    }
                    catch ( IOException e )
                    {
                        Logger.getLogger( Server.class.getName() ).log( Level.SEVERE, "", e );
                    }
                    finally
                    {
                        if ( r != null )
                        {
                            try
                            {
                                r.close();
                            }
                            catch ( IOException e )
                            {
                            }
                        }
                        if ( sock != null )
                        {
                            try
                            {
                                sock.close();
                            }
                            catch ( IOException e )
                            {
                            }
                        }
                    }
                }
            }
            finally
            {
                if ( ssock != null )
                {
                    try
                    {
                        ssock.close();
                    }
                    catch ( IOException e )
                    {
                    }
                }
            }
        }
    }
}
