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 java.io.File;
import java.util.List;
import java.util.regex.Pattern;

import org.apache.maven.it.util.ResourceExtractor;

/**
 * This is a test set for <a href="https://issues.apache.org/jira/browse/MNG-3641">MNG-3641</a>:
 * Profile activation warning test
 */
public class MavenITmng3641ProfileActivationWarningTest
    extends AbstractMavenIntegrationTestCase
{

    public MavenITmng3641ProfileActivationWarningTest()
    {
        super( "[2.0.11,2.1.0-M1),[2.1.0,)" ); // only test in 2.0.11+, 2.1.0+
    }

    public void testitMNG3641()
        throws Exception
    {
        // (0) Initialize.
        File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-3641" );

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

        // Delete this artifact. Just in case.
        verifier.deleteArtifact( "org.apache.maven.its.mng3641", "parent", "1.0", "pom" );

        // (1) make sure the profile is found. Must not contain a warning.
        verifier.addCliOption( "-P mng-3641-it-provided-profile" );
        verifier.setLogFileName( "log-1.txt" );
        verifier.executeGoal( "validate" );
        verifier.verifyErrorFreeLog();
        verifier.resetStreams();

        List<String> logFile = verifier.loadFile( verifier.getBasedir(), verifier.getLogFileName(), false );
        assertNull( findWarning( logFile, "mng-3641-it-provided-profile" ) );

        // (2) make sure the profile was not found and a warning was printed.
        verifier = newVerifier( testDir.getAbsolutePath() );
        verifier.addCliOption( "-P mng-3641-TWlzdGVyIFQgd2FzIGhlcmUuICheX14p" );
        verifier.setLogFileName( "log-2.txt" );
        verifier.executeGoal( "validate" );
        verifier.verifyErrorFreeLog();
        verifier.resetStreams();

        logFile = verifier.loadFile( verifier.getBasedir(), verifier.getLogFileName(), false );
        assertNotNull( findWarning( logFile, "mng-3641-TWlzdGVyIFQgd2FzIGhlcmUuICheX14p" ) );

        // (3) make sure the first profile is found while the other is not and a warning was printed
        // accordingly.
        verifier = newVerifier( testDir.getAbsolutePath() );
        verifier.addCliOption( "-P mng-3641-it-provided-profile,mng-3641-TWlzdGVyIFQgd2FzIGhlcmUuICheX14p" );
        verifier.setLogFileName( "log-3.txt" );
        verifier.executeGoal( "validate" );
        verifier.verifyErrorFreeLog();
        verifier.resetStreams();

        logFile = verifier.loadFile( verifier.getBasedir(), verifier.getLogFileName(), false );
        assertNull( findWarning( logFile, "mng-3641-it-provided-profile" ) );
        assertNotNull( findWarning( logFile, "mng-3641-TWlzdGVyIFQgd2FzIGhlcmUuICheX14p" ) );

        // (4) make sure the warning is only printed when the profile is missing in all projects
        verifier = newVerifier( testDir.getAbsolutePath() );
        verifier.addCliOption( "-P mng-3641-it-provided-profile-child" );
        verifier.setLogFileName( "log-4.txt" );
        verifier.executeGoal( "validate" );
        verifier.verifyErrorFreeLog();
        verifier.resetStreams();

        logFile = verifier.loadFile( verifier.getBasedir(), verifier.getLogFileName(), false );
        assertNull( findWarning( logFile, "mng-3641-it-provided-profile-child" ) );

        // (5) make sure the profile is found in subproject. Must not contain a warning.
        verifier = newVerifier( new File( testDir, "child1" ).getAbsolutePath() );
        verifier.addCliOption( "-P mng-3641-it-provided-profile-child" );
        verifier.setLogFileName( "log-5.txt" );
        verifier.executeGoal( "validate" );
        verifier.verifyErrorFreeLog();
        verifier.resetStreams();

        logFile = verifier.loadFile( verifier.getBasedir(), verifier.getLogFileName(), false );
        assertNull( findWarning( logFile, "mng-3641-it-provided-profile-child" ) );

        // (6) make sure the profile is found from parent in subproject. Must not contain a warning.
        verifier = newVerifier( new File( testDir, "child1" ).getAbsolutePath() );
        verifier.addCliOption( "-P mng-3641-it-provided-profile" );
        verifier.setLogFileName( "log-6.txt" );
        verifier.executeGoal( "validate" );
        verifier.verifyErrorFreeLog();
        verifier.resetStreams();

        logFile = verifier.loadFile( verifier.getBasedir(), verifier.getLogFileName(), false );
        assertNull( findWarning( logFile, "mng-3641-it-provided-profile" ) );
    }

    private String findWarning( List<String> logLines, String profileId )
    {
        Pattern pattern = Pattern.compile( "(?i).*profile\\s.*\\Q" + profileId + "\\E.*\\snot\\s.*activated.*" );

        for ( String logLine : logLines )
        {
            if ( pattern.matcher( logLine ).matches() )
            {
                return logLine;
            }
        }

        return null;
    }

}
