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

/**
 * This is a test set for <a href="https://issues.apache.org/jira/browse/MNG-3379">MNG-3379</a>.
 * 
 * @author Benjamin Bentmann
 *
 */
public class MavenITmng3379ParallelArtifactDownloadsTest
    extends AbstractMavenIntegrationTestCase
{

    public MavenITmng3379ParallelArtifactDownloadsTest()
    {
        super( "[2.0.5,3.0-alpha-1),[3.0-alpha-2,)" );
    }

    /**
     * Tests that parallel downloads of artifacts from both the same and from different group ids don't corrupt
     * the local repo.
     */
    public void testitMNG3379()
        throws Exception
    {
        File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-3379" );

        Verifier verifier = newVerifier( testDir.getAbsolutePath() );
        verifier.setAutoclean( false );
        verifier.deleteArtifacts( "org.apache.maven.its.mng3379.a" );
        verifier.deleteArtifacts( "org.apache.maven.its.mng3379.b" );
        verifier.deleteArtifacts( "org.apache.maven.its.mng3379.c" );
        verifier.deleteArtifacts( "org.apache.maven.its.mng3379.d" );
        verifier.filterFile( "settings-template.xml", "settings.xml", "UTF-8", verifier.newDefaultFilterProperties() );
        verifier.addCliOption( "--settings" );
        verifier.addCliOption( "settings.xml" );
        verifier.setSystemProperty( "maven.artifact.threads", "16" );
        verifier.executeGoal( "validate" );
        verifier.verifyErrorFreeLog();
        verifier.resetStreams();

        String gid = "org.apache.maven.its.mng3379.";
        assertArtifact( verifier, gid + "a", "x", "0.2-SNAPSHOT", "", "jar",
            "69c041c12f35894230c7c23c49cd245886c6fb6f" );
        assertArtifact( verifier, gid + "a", "x", "0.2-SNAPSHOT", "", "pom",
            "f0abcb2aa6d99f045c013ecb2671a3a3e71bd715" );
        assertArtifact( verifier, gid + "a", "x", "0.2-SNAPSHOT", "tests", "jar",
            "69c041c12f35894230c7c23c49cd245886c6fb6f" );
        assertArtifact( verifier, gid + "a", "x", "0.2-SNAPSHOT", "sources", "jar",
            "166f8bef02b9e92f99ec3b163d8321dd1d087e34" );
        assertArtifact( verifier, gid + "a", "x", "0.2-SNAPSHOT", "javadoc", "jar",
            "4d96e09f7e93870685a317c574f851b407224415" );
        assertMetadata( verifier, gid + "a", "x", "0.2-SNAPSHOT",
            "e1cfc3a77657fc46bb624dee25c61b290e5b4dd7" );
        
        assertArtifact( verifier, gid + "b", "x", "0.2-SNAPSHOT", "", "jar",
            "efb7c4046565774cd7e44645e02f06ecdf91098d" );
        assertArtifact( verifier, gid + "b", "x", "0.2-SNAPSHOT", "", "pom",
            "a057baebe5cdae3978b530c0bfea8b523b3d4506" );
        assertArtifact( verifier, gid + "b", "x", "0.2-SNAPSHOT", "tests", "jar",
            "efb7c4046565774cd7e44645e02f06ecdf91098d" );
        assertArtifact( verifier, gid + "b", "x", "0.2-SNAPSHOT", "sources", "jar",
            "9ad231fc04ea1114987c377cc5cbccfbf83e3dbf" );
        assertArtifact( verifier, gid + "b", "x", "0.2-SNAPSHOT", "javadoc", "jar",
            "7807daefd3af3be73d3b92f9c5ab1b52510c0767" );
        assertMetadata( verifier, gid + "b", "x", "0.2-SNAPSHOT",
            "5ccc4edfb503f9a5ccadedf102dff8943250d830" );
        assertMetadata( verifier, gid + "b", "x",
            "8f38b1041871f22dcb031544d8a3436c335bfcdb" );

        assertArtifact( verifier, gid + "c", "x", "0.2-SNAPSHOT", "", "jar",
            "1eb0d5a421b3074e8a69b0dcca7e325c0636a932" );
        assertArtifact( verifier, gid + "c", "x", "0.2-SNAPSHOT", "", "pom",
            "9c993bdebc7bd1b673891f203511fed9085996f3" );
        assertArtifact( verifier, gid + "c", "x", "0.2-SNAPSHOT", "tests", "jar",
            "1eb0d5a421b3074e8a69b0dcca7e325c0636a932" );
        assertArtifact( verifier, gid + "c", "x", "0.2-SNAPSHOT", "sources", "jar",
            "82f9664b3a910fb861fc4ed2b79e39d8f95e3675" );
        assertArtifact( verifier, gid + "c", "x", "0.2-SNAPSHOT", "javadoc", "jar",
            "64a3bfe19b294f67b1c52a2514c58922b88e5f97" );
        assertMetadata( verifier, gid + "c", "x", "0.2-SNAPSHOT",
            "b31ef40a51bdab4e6e44bfe3f2d1da42e5e42e46" );
        assertMetadata( verifier, gid + "c", "x",
            "c4848e60d226ec6304df3abd9eba8fdb301b3660" );

        assertArtifact( verifier, gid + "d", "x", "0.2-SNAPSHOT", "", "jar",
            "3d606c564625a594165bcbbe4a24c8f11b18b5a0" );
        assertArtifact( verifier, gid + "d", "x", "0.2-SNAPSHOT", "", "pom",
            "e7b6322cea42970e61316b161f79da690f042f7e" );
        assertArtifact( verifier, gid + "d", "x", "0.2-SNAPSHOT", "tests", "jar",
            "3d606c564625a594165bcbbe4a24c8f11b18b5a0" );
        assertArtifact( verifier, gid + "d", "x", "0.2-SNAPSHOT", "sources", "jar",
            "35a7e140307f4bb67984dc72aa551f0faabacd36" );
        assertArtifact( verifier, gid + "d", "x", "0.2-SNAPSHOT", "javadoc", "jar",
            "2fe3487f496fe66f23772b1bada066ec6bd9222f" );
        assertMetadata( verifier, gid + "d", "x", "0.2-SNAPSHOT",
            "a0d0b5efd5d6f6a921a3f7c1a6a503359fccef04" );
        assertMetadata( verifier, gid + "d", "x",
            "1d2bf926862f2131f1229328e588b906b087bdb3" );
    }

    private void assertArtifact( Verifier verifier, String gid, String aid, String ver, String cls, String ext, String sha1 )
        throws Exception
    {
        File file = new File( verifier.getArtifactPath( gid, aid, ver, ext, cls ) );
        assertTrue( file.getAbsolutePath(), file.isFile() );
        assertEquals( sha1, ItUtils.calcHash( file, "SHA-1" ) );
    }

    private void assertMetadata( Verifier verifier, String gid, String aid, String ver, String sha1 )
        throws Exception
    {
        String name = "maven-metadata-maven-core-it.xml";
        File file = new File( verifier.getArtifactMetadataPath( gid, aid, ver, name ) );
        assertTrue( file.getAbsolutePath(), file.isFile() );
        assertEquals( sha1, ItUtils.calcHash( file, "SHA-1" ) );
    }

    private void assertMetadata( Verifier verifier, String gid, String aid, String sha1 )
        throws Exception
    {
        String name = "maven-metadata-maven-core-it.xml";
        File file = new File( verifier.getArtifactMetadataPath( gid, aid, null, name ) );
        assertTrue( file.getAbsolutePath(), file.isFile() );
        assertEquals( sha1, ItUtils.calcHash( file, "SHA-1" ) );
    }

}
