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.Verifier;
import org.apache.maven.it.util.ResourceExtractor;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

/**
 * Using a <code>${revision}</code> in the version will change the reactor order before fixing
 * <a href="https://issues.apache.org/jira/browse/MNG-6057">MNG-6057</a>. Without the fix for this issue the order of
 * the reactor is changed in that way that the parent is ordered to the last position instead of the first position.
 * 
 * @author Karl Heinz Marbaise khmarbaise@apache.org
 */
public class MavenITmng6057CheckReactorOrderTest
    extends AbstractMavenIntegrationTestCase
{

    public MavenITmng6057CheckReactorOrderTest()
    {
        // The first version which contains the fix for the MNG-6057 issue.
        // TODO: Think about it!
        super( "[3.5.0-alpha-2,)" );
    }

    /**
     * Verify that the result shows the reactor order as expected.
     */
    public void testitReactorShouldResultInExpectedOrder()
        throws Exception
    {
        File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-6057-check-reactor-order" );

        Verifier verifier = newVerifier( testDir.getAbsolutePath(), false );
        verifier.setMavenDebug( false );
        verifier.setAutoclean( false );

        verifier.setLogFileName( "log-only.txt" );
        verifier.addCliOption( "-Drevision=1.3.0-SNAPSHOT" );
        verifier.executeGoal( "clean" );
        verifier.verifyErrorFreeLog();
        verifier.resetStreams();

        List<String> loadedLines = verifier.loadLines( "log-only.txt", "UTF-8" );
        List<String> resultingLines = extractReactorBuildOrder( loadedLines );

        // We expecting exactly three lines as result.
        assertEquals( 3, resultingLines.size() );

        // We expect those lines in the following exact order.
        assertTrue( resultingLines.get( 0 ).startsWith( "[INFO] base-project" ) );
        assertTrue( resultingLines.get( 1 ).startsWith( "[INFO] module-1" ) );
        assertTrue( resultingLines.get( 2 ).startsWith( "[INFO] module-2" ) );
    }

    /**
     * Extract the lines at the beginning of the Maven output:
     * 
     * <pre>
     * [INFO] Reactor Build Order:
     * [INFO]
     * [INFO] module-1
     * [INFO] module-2
     * [INFO] base-project
     * [INFO]
     * </pre>
     */
    private List<String> extractReactorBuildOrder( List<String> loadedLines )
    {
        List<String> resultingLines = new LinkedList<String>();
        boolean start = false;
        for ( String line : loadedLines )
        {
            if ( start )
            {
                if ( line.startsWith( "[INFO] -------------" ) )
                {
                    start = false;
                }
                else if ( !line.endsWith( "[INFO] " ) )
                {
                    resultingLines.add( line );
                }
            }
            else
            {
                if ( line.startsWith( "[INFO] Reactor Build Order:" ) )
                {
                    start = true;
                }

            }
        }
        return resultingLines;

    }

}
