package org.apache.maven.plugins.dependency.utils.markers;

/* 
 * 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.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import junit.framework.TestCase;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.artifact.handler.ArtifactHandler;
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.dependency.testUtils.stubs.StubSourcesFileMarkerHandler;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.testing.SilentLog;

/**
 * @author brianf
 */
public class TestSourcesMarkerFileHandler
    extends TestCase
{
    List<Artifact> artifacts = new ArrayList<>();

    Log log = new SilentLog();

    File outputFolder;

    protected void setUp()
        throws Exception
    {
        super.setUp();

        ArtifactHandler ah = new DefaultArtifactHandler();
        VersionRange vr = VersionRange.createFromVersion( "1.1" );
        Artifact artifact = new DefaultArtifact( "test", "1", vr, Artifact.SCOPE_COMPILE, "jar", "", ah, false );
        artifacts.add( artifact );
        artifact = new DefaultArtifact( "test", "2", vr, Artifact.SCOPE_PROVIDED, "war", "", ah, false );
        artifacts.add( artifact );
        artifact = new DefaultArtifact( "test", "3", vr, Artifact.SCOPE_TEST, "sources", "", ah, false );
        artifacts.add( artifact );
        artifact = new DefaultArtifact( "test", "4", vr, Artifact.SCOPE_RUNTIME, "zip", "", ah, false );
        artifacts.add( artifact );

        // pick random output location
        Random a = new Random();
        outputFolder = new File( "target/markers" + a.nextLong() + "/" );
        outputFolder.delete();
        assertFalse( outputFolder.exists() );
    }

    protected void tearDown()
    {
        outputFolder.delete();
    }

    public void testSetMarkerResolved()
        throws MojoExecutionException
    {
        DefaultFileMarkerHandler handler = new SourcesFileMarkerHandler( artifacts.get( 0 ), this.outputFolder, true );
        assertFalse( handler.isMarkerSet() );
        handler.setMarker();
        assertTrue( handler.isMarkerSet() );
        handler.clearMarker();
        assertFalse( handler.isMarkerSet() );

        handler.setMarker();
        handler.setMarker();
        assertTrue( handler.isMarkerSet() );

        handler.clearMarker();
        handler.clearMarker();
        outputFolder.delete();
        assertFalse( outputFolder.exists() );
    }

    public void testSetMarkerUnresolved()
        throws MojoExecutionException
    {
        DefaultFileMarkerHandler handler = new SourcesFileMarkerHandler( artifacts.get( 0 ), this.outputFolder, false );
        assertFalse( handler.isMarkerSet() );
        handler.setMarker();
        assertTrue( handler.isMarkerSet() );
        handler.clearMarker();
        assertFalse( handler.isMarkerSet() );

        handler.setMarker();
        handler.setMarker();
        assertTrue( handler.isMarkerSet() );

        handler.clearMarker();
        handler.clearMarker();
        outputFolder.delete();
        assertFalse( outputFolder.exists() );
    }

    public void testBothMarkers()
        throws MojoExecutionException
    {
        DefaultFileMarkerHandler handler = new SourcesFileMarkerHandler( artifacts.get( 1 ), this.outputFolder, true );
        DefaultFileMarkerHandler handler2 =
            new SourcesFileMarkerHandler( artifacts.get( 1 ), this.outputFolder, false );

        handler.setMarker();
        assertTrue( handler.isMarkerSet() );
        assertTrue( handler2.isMarkerSet() );

        handler2.clearMarker();
        assertFalse( handler.isMarkerSet() );
        assertFalse( handler2.isMarkerSet() );
        outputFolder.delete();
        assertFalse( outputFolder.exists() );
    }

    public void testMarkerFile()
        throws MojoExecutionException, IOException
    {
        DefaultFileMarkerHandler handler = new SourcesFileMarkerHandler( artifacts.get( 0 ), this.outputFolder, true );
        DefaultFileMarkerHandler handler2 =
            new SourcesFileMarkerHandler( artifacts.get( 0 ), this.outputFolder, false );

        File handle = handler.getMarkerFile();
        File handle2 = handler2.getMarkerFile();
        assertFalse( handle.exists() );
        assertFalse( handler.isMarkerSet() );
        assertFalse( handle2.exists() );
        assertFalse( handler2.isMarkerSet() );

        // if either file exists, the marker is set
        handler.setMarker();
        assertTrue( handler.isMarkerSet() );
        assertTrue( handle.exists() );
        assertTrue( handler2.isMarkerSet() );
        assertFalse( handle2.exists() );

        // if either file exists, the marker is set
        // setting 1 will clear the other marker
        handler2.setMarker();
        assertTrue( handler.isMarkerSet() );
        assertFalse( handle.exists() );
        assertTrue( handler2.isMarkerSet() );
        assertTrue( handle2.exists() );

        // reset file for next test
        handle.createNewFile();

        // only delete one, should be still true
        handle2.delete();
        assertTrue( handler.isMarkerSet() );
        assertTrue( handler2.isMarkerSet() );

        // delete the 2nd, should be false.
        handle.delete();
        assertFalse( handler.isMarkerSet() );
        assertFalse( handler2.isMarkerSet() );

        handle.createNewFile();
        assertTrue( handler.isMarkerSet() );
        assertTrue( handler2.isMarkerSet() );

        handler.clearMarker();
        assertFalse( handle.exists() );
        handler2.clearMarker();
        assertFalse( handle2.exists() );

        handle.delete();
        handle2.delete();

        outputFolder.delete();
        assertFalse( outputFolder.exists() );
    }

    public void testMarkerTimeStampResolved()
        throws MojoExecutionException, IOException, InterruptedException
    {
        doTestMarkerTimeStamp( true );
    }

    public void testMarkerTimeStampUnResolved()
        throws MojoExecutionException, IOException, InterruptedException
    {
        doTestMarkerTimeStamp( false );
    }

    public void doTestMarkerTimeStamp( boolean resolved )
        throws MojoExecutionException, IOException, InterruptedException
    {
        File theFile = new File( outputFolder, "theFile.jar" );
        outputFolder.mkdirs();
        theFile.createNewFile();
        Artifact theArtifact = artifacts.get( 0 );
        theArtifact.setFile( theFile );
        SourcesFileMarkerHandler resolvedHandler =
            new SourcesFileMarkerHandler( artifacts.get( 0 ), this.outputFolder, resolved );
        SourcesFileMarkerHandler unResolvedHandler =
            new SourcesFileMarkerHandler( artifacts.get( 0 ), this.outputFolder, !resolved );

        assertFalse( resolvedHandler.isMarkerSet() );
        assertFalse( unResolvedHandler.isMarkerSet() );
        // if the marker is not set, assume it is infinately older than the
        // artifact.
        assertTrue( resolvedHandler.isMarkerOlder( theArtifact ) );
        assertTrue( unResolvedHandler.isMarkerOlder( theArtifact ) );
        resolvedHandler.setMarker();
        assertFalse( resolvedHandler.isMarkerOlder( theArtifact ) );
        assertFalse( unResolvedHandler.isMarkerOlder( theArtifact ) );

        resolvedHandler.clearMarker();
        unResolvedHandler.setMarker();
        assertFalse( resolvedHandler.isMarkerOlder( theArtifact ) );
        assertFalse( unResolvedHandler.isMarkerOlder( theArtifact ) );

        assertTrue( theFile.setLastModified( theFile.lastModified() + 60000 ) );
        assertTrue( resolvedHandler.isMarkerOlder( theArtifact ) );
        assertTrue( unResolvedHandler.isMarkerOlder( theArtifact ) );

        theFile.delete();
        resolvedHandler.clearMarker();
        assertFalse( resolvedHandler.isMarkerSet() );
    }

    public void testMarkerFileException()
    {
        // this stub wraps the file with an object to throw exceptions
        StubSourcesFileMarkerHandler handler =
            new StubSourcesFileMarkerHandler( artifacts.get( 0 ), this.outputFolder, true );
        try
        {
            handler.setMarker();
            fail( "Expected an Exception here" );
        }
        catch ( MojoExecutionException e )
        {
        }
    }

    public void testMarkerFileResolvedSetter()
    {
        SourcesFileMarkerHandler handler = new SourcesFileMarkerHandler( null, null, true );
        assertTrue( handler.isResolved() );
        handler.setResolved( false );
        assertFalse( handler.isResolved() );
    }

    public void testNullParent()
        throws MojoExecutionException
    {
        // the parent isn't set so this will create the marker in the local
        // folder. We must clear the
        // marker to avoid leaving test droppings in root.
        DefaultFileMarkerHandler handler = new SourcesFileMarkerHandler( null, null, false );
        handler.setArtifact( artifacts.get( 0 ) );
        handler.setMarker();
        assertTrue( handler.isMarkerSet() );
        handler.clearMarker();
        assertFalse( handler.isMarkerSet() );
    }

    public void testNullParentResolved()
        throws MojoExecutionException
    {
        // the parent isn't set so this will create the marker in the local
        // folder. We must clear the
        // marker to avoid leaving test droppings in root.
        DefaultFileMarkerHandler handler = new SourcesFileMarkerHandler( null, null, true );
        handler.setArtifact( artifacts.get( 0 ) );
        handler.setMarker();
        assertTrue( handler.isMarkerSet() );
        handler.clearMarker();
        assertFalse( handler.isMarkerSet() );

    }
}
