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.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

/**
 * An integration test to ensure any pomfile is only read once.
 * This is confirmed by adding a Java Agent to the DefaultModelReader and output the options, including the source location
 *
 * <a href="https://issues.apache.org/jira/browse/MNG-5669">MNG-5669</a>.
 *
 */
public class MavenITmng5669ReadPomsOnce
    extends AbstractMavenIntegrationTestCase
{

    public MavenITmng5669ReadPomsOnce()
    {
        super( "[4.0.0-alpha-1,)" );
    }

    public void testWithoutBuildConsumer()
        throws Exception
    {
        // prepare JavaAgent
        File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-5669-read-poms-once" );
        Verifier verifier = newVerifier( testDir.getAbsolutePath(), false );
        Map<String, String> filterProperties =
            Collections.singletonMap( "${javaAgentJar}",
                                      verifier.getArtifactPath( "mng-coreit", "javaagent", "1.0-SNAPSHOT", "jar" ) );
        verifier.filterFile( ".mvn/jvm.config", ".mvn/jvm.config", null, filterProperties );

        verifier.setForkJvm( true ); // pick up agent
        verifier.setMavenDebug( false );
        verifier.setAutoclean( false );
        verifier.addCliOption( "-q" );
        verifier.addCliOption( "-U" );
        verifier.addCliOption( "-Dmaven.experimental.buildconsumer=false" );
        verifier.executeGoals( Arrays.asList( "verify" ) );
        verifier.resetStreams();

        List<String> logTxt = verifier.loadLines( "log.txt", "utf-8" );
        for ( String line : logTxt )
        {
            if ( line.startsWith( "Picked up JAVA_TOOL_OPTIONS:" ) )
            {
                logTxt.remove( line );
                break;
            }
        }
        assertEquals( logTxt.toString(), 168, logTxt.size() );

        // analyze lines. It is a Hashmap, so we can't rely on the order
        Set<String> uniqueBuildingSources = new HashSet<>( 168 );
        final String buildSourceKey = "org.apache.maven.model.building.source=";
        final int keyLength = buildSourceKey.length();
        for ( String line : logTxt )
        {
            int start = line.indexOf( buildSourceKey );
            if ( start < 0 )
            {
                continue;
            }

            int end = line.indexOf( ", ", start );
            if ( end < 0 )
            {
                end = line.length() - 1; // is the }
            }
            uniqueBuildingSources.add( line.substring( start + keyLength, end ) );
        }
        assertEquals( uniqueBuildingSources.size(), 167 /* is 168 minus superpom */ );
    }

    public void testWithBuildConsumer()
        throws Exception
    {
        // prepare JavaAgent
        File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-5669-read-poms-once" );
        Verifier verifier = newVerifier( testDir.getAbsolutePath(), false );
        Map<String, String> filterProperties =
            Collections.singletonMap( "${javaAgentJar}",
                                      verifier.getArtifactPath( "mng-coreit", "javaagent", "1.0-SNAPSHOT", "jar" ) );
        verifier.filterFile( ".mvn/jvm.config", ".mvn/jvm.config", null, filterProperties );

        verifier.setForkJvm( true ); // pick up agent
        verifier.setMavenDebug( false );
        verifier.setAutoclean( false );
        verifier.addCliOption( "-q" );
        verifier.addCliOption( "-U" );
        verifier.addCliOption( "-Dmaven.experimental.buildconsumer=true" );
        verifier.executeGoals( Arrays.asList( "verify" ) );
        verifier.resetStreams();

        List<String> logTxt = verifier.loadLines( "log.txt", "utf-8" );
        for ( String line : logTxt )
        {
            if ( line.startsWith( "Picked up JAVA_TOOL_OPTIONS:" ) )
            {
                logTxt.remove( line );
                break;
            }
        }
        assertEquals( logTxt.toString(), 168 + 4 /* reactor poms are read twice: file + raw (=XMLFilters) */,
                      logTxt.size() );

        // analyze lines. It is a Hashmap, so we can't rely on the order
        Set<String> uniqueBuildingSources = new HashSet<>( 168 );
        final String buildSourceKey = "org.apache.maven.model.building.source=";
        final int keyLength = buildSourceKey.length();
        for ( String line : logTxt )
        {
            int start = line.indexOf( buildSourceKey );
            if ( start < 0 )
            {
                continue;
            }

            int end = line.indexOf( ", ", start );
            if ( end < 0 )
            {
                end = line.length() - 1; // is the }
            }
            uniqueBuildingSources.add( line.substring( start + keyLength, end ) );
        }
        assertEquals( uniqueBuildingSources.size(), 167 /* is 168 minus superpom */ );
    }

}
