package org.apache.maven.it;

/*
 * 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.it.util.ResourceExtractor;
import org.eclipse.jetty.server.NetworkConnector;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Properties;

/**
 * This is a test set for <a href="https://issues.apache.org/jira/browse/MNG-5280">MNG-5280</a>.
 * 
 * @author Anders Hammar
 */
public class MavenITmng5280SettingsProfilesRepositoriesOrderTest
    extends AbstractMavenIntegrationTestCase
{
    private File testDir;

    private Server server;

    public MavenITmng5280SettingsProfilesRepositoriesOrderTest()
    {
        super( "[3.1-A,)" );
    }

    @Override
    protected void setUp()
        throws Exception
    {
        testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-5280" );
        server = new Server( 0 );
    }

    @Override
    protected void tearDown()
        throws Exception
    {
        if ( server != null )
        {
            server.stop();
            server.join();
        }
    }

    /**
     * Verify that the repositories are used in the reversed order of definition in settings.xml.
     */
    public void testRepositoriesOrder()
        throws Exception
    {
        RepoHandler repoHandler = new RepoHandler();
        server.setHandler( repoHandler );
        server.start();
        if ( server.isFailed() )
        {
            fail( "Couldn't bind the server socket to a free port!" );
        }
        int httpPort = ( (NetworkConnector) server.getConnectors()[0] ).getLocalPort();
        System.out.println( "Bound server socket to the port " + httpPort );

        Verifier verifier = newVerifier( testDir.getAbsolutePath() );

        verifier.setAutoclean( false );
        verifier.deleteDirectory( "target" );
        verifier.deleteArtifacts( "org.apache.maven.its.mng5280" );
        Properties filterProps = verifier.newDefaultFilterProperties();
        filterProps.setProperty( "@httpserver.port@", Integer.toString( httpPort ) );
        verifier.filterFile( "settings-template.xml", "settings.xml", "UTF-8", filterProps );
        verifier.addCliOption( "--settings" );
        verifier.addCliOption( "settings.xml" );
        verifier.executeGoal( "org.apache.maven.its.plugins:maven-it-plugin-dependency-resolution:2.1-SNAPSHOT:compile" );
        verifier.verifyErrorFreeLog();
        verifier.resetStreams();

        assertTrue( repoHandler.artifactRequestedFromRepo2 );
        assertTrue( repoHandler.artifactRequestedFromRepo1Last );
    }

    /**
     * Verify that the plugin repositories are used in the reversed order of definition in settings.xml.
     */
    public void testPluginRepositoriesOrder()
        throws Exception
    {
        PluginRepoHandler pluginRepoHandler = new PluginRepoHandler();
        server.setHandler( pluginRepoHandler );
        server.start();
        if ( server.isFailed() )
        {
            fail( "Couldn't bind the server socket to a free port!" );
        }
        int httpPort = ( (NetworkConnector) server.getConnectors()[0] ).getLocalPort();
        System.out.println( "Bound server socket to the port " + httpPort );

        Verifier verifier = newVerifier( testDir.getAbsolutePath() );

        verifier.setAutoclean( false );
        verifier.deleteDirectory( "target" );
        verifier.deleteArtifacts( "org.apache.maven.its.mng5280" );
        Properties filterProps = verifier.newDefaultFilterProperties();
        filterProps.setProperty( "@httpserver.port@", Integer.toString( httpPort ) );
        verifier.filterFile( "settings-template.xml", "settings.xml", "UTF-8", filterProps );
        verifier.addCliOption( "--settings" );
        verifier.addCliOption( "settings.xml" );
        verifier.executeGoal( "org.apache.maven.its.mng5280:fake-maven-plugin:1.0:fake" );
        verifier.resetStreams();

        assertTrue( pluginRepoHandler.pluginRequestedFromRepo2 );
        assertTrue( pluginRepoHandler.pluginRequestedFromRepo1Last );
    }

    private static final class RepoHandler
        extends AbstractHandler
    {
        private volatile boolean artifactRequestedFromRepo1Last;

        private volatile boolean artifactRequestedFromRepo2;

        public void handle( String target, Request baseRequest, HttpServletRequest request,
                            HttpServletResponse response )
            throws IOException
        {
            String uri = request.getRequestURI();

            if ( uri.startsWith( "/repo1/org/apache/maven/its/mng5280/fake-artifact/1.0/" ) )
            {
                PrintWriter writer = response.getWriter();

                if ( uri.endsWith( ".pom" ) )
                {
                    writer.println( "<project>" );
                    writer.println( "  <modelVersion>4.0.0</modelVersion>" );
                    writer.println( "  <groupId>org.apache.maven.its.mng5280</groupId>" );
                    writer.println( "  <artifactId>fake-artifact</artifactId>" );
                    writer.println( "  <version>1.0</version>" );
                    writer.println( "</project>" );
                    
                    response.setStatus( HttpServletResponse.SC_OK );
                }
                else if ( uri.endsWith( ".jar" ) )
                {
                    writer.println( "empty" );

                    response.setStatus( HttpServletResponse.SC_OK );
                    artifactRequestedFromRepo1Last = true;
                }
                else
                {
                    response.setStatus( HttpServletResponse.SC_NOT_FOUND );
                }
            }
            else if ( uri.startsWith( "/repo2/org/apache/maven/its/mng5280/fake-artifact/1.0/" ) )
            {
                if ( uri.endsWith( ".jar" ) )
                {
                    artifactRequestedFromRepo1Last = false;
                    artifactRequestedFromRepo2 = true;
                }
                response.setStatus( HttpServletResponse.SC_NOT_FOUND );
            }
            else
            {
                response.setStatus( HttpServletResponse.SC_NOT_FOUND );
            }

            ( (Request) request ).setHandled( true );
        }
    }

    private class PluginRepoHandler
        extends AbstractHandler
    {
        private volatile boolean pluginRequestedFromRepo1Last;

        private volatile boolean pluginRequestedFromRepo2;

        public void handle( String target, Request baseRequest, HttpServletRequest request,
                            HttpServletResponse response )
            throws IOException
        {
            String uri = request.getRequestURI();

            if ( uri.startsWith( "/pluginRepo1/org/apache/maven/its/mng5280/fake-maven-plugin/1.0/" ) )
            {
                OutputStream outStream = response.getOutputStream();

                if ( uri.endsWith( ".pom" ) )
                {
                    File pluginPom = new File( testDir, "fake-maven-plugin/fake-maven-plugin-1.0.pom" );
                    InputStream inStream = new FileInputStream( pluginPom );
                    copy( inStream, outStream );

                    response.setStatus( HttpServletResponse.SC_OK );
                }
                else if ( uri.endsWith( ".jar" ) )
                {
                    File pluginJar = new File( testDir, "fake-maven-plugin/fake-maven-plugin-1.0.jar" );
                    InputStream inStream = new FileInputStream( pluginJar );
                    copy( inStream, outStream );

                    response.setStatus( HttpServletResponse.SC_OK );
                    pluginRequestedFromRepo1Last = true;
                }
                else
                {
                    response.setStatus( HttpServletResponse.SC_NOT_FOUND );
                }
            }
            else if ( uri.startsWith( "/pluginRepo2/org/apache/maven/its/mng5280/fake-maven-plugin/1.0/" ) )
            {
                if ( uri.endsWith( ".jar" ) )
                {
                    pluginRequestedFromRepo1Last = false;
                    pluginRequestedFromRepo2 = true;
                }
                response.setStatus( HttpServletResponse.SC_NOT_FOUND );
            }
            else
            {
                response.setStatus( HttpServletResponse.SC_NOT_FOUND );
            }

            ( (Request) request ).setHandled( true );
        }

        private long copy( InputStream input, OutputStream output )
            throws IOException
        {
            byte[] buffer = new byte[4 * 1024];
            long count = 0;
            int n = 0;
            while ( -1 != ( n = input.read( buffer ) ) )
            {
                output.write( buffer, 0, n );
                count += n;
            }
            return count;
        }
    }
}
