package org.apache.maven.plugin.changelog;

/*
 * 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.plugin.changelog.stubs.ScmManagerStub;
import org.apache.maven.plugin.changelog.stubs.FailedScmManagerStub;
import org.apache.maven.plugin.changelog.stubs.ScmManagerWithHostStub;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.scm.manager.ScmManager;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;

/**
 * @author Edwin Punzalan
 * @version $Id$
 */
public class ChangeLogReportTest
    extends AbstractChangeLogReportTest
{
    private ScmManager scmManager;

    /** {@inheritDoc} */
    protected void setUp()
        throws Exception
    {
        super.setUp();

        scmManager = new ScmManagerStub();
    }

    /** {@inheritDoc} */
    protected void tearDown()
        throws Exception
    {
        super.tearDown();

        scmManager = null;
    }

    public void testNoSource()
        throws Exception
    {
        File pluginXmlFile = new File( getBasedir(), "src/test/plugin-configs/changelog/no-source-plugin-config.xml" );

        ChangeLogReport mojo = (ChangeLogReport)lookupMojo( "changelog", pluginXmlFile );

        assertNotNull( "Mojo found.", mojo );

        this.setVariableValueToObject( mojo, "manager", scmManager );

        mojo.execute();

        File outputDir = (File) getVariableValueFromObject( mojo, "outputDirectory" );

        File outputHtml = new File( outputDir, "changelog.html" );

        renderer( mojo, outputHtml );

        assertTrue( outputHtml.getAbsolutePath() + " not generated!", outputHtml.exists() );

        assertTrue( outputHtml.getAbsolutePath() + " is empty!", outputHtml.length() > 0 );
    }

    public void testMinConfig()
        throws Exception
    {
        executeMojo( "min-plugin-config.xml" );
    }

    public void testFailedChangelog()
        throws Exception
    {
        scmManager = new FailedScmManagerStub();

        try
        {
            executeMojo( "min-plugin-config.xml" );
        }
        catch ( MojoExecutionException e )
        {
            assertEquals( "Test thrown exception", "Command failed.", e.getCause().getCause().getMessage() );
        }
    }

    public void testUsageOfCachedXml()
        throws Exception
    {
        File cacheFile = new File( getBasedir(), "src/test/changelog-xml/min-changelog.xml" );
        cacheFile.setLastModified( System.currentTimeMillis() );

        executeMojo( "cached-plugin-config.xml" );
    }

    public void testTypeException()
        throws Exception
    {
        try
        {
            executeMojo( "inv-type-plugin-config.xml" );

            fail( "Test exception on invalid type" );
        }
        catch ( MojoExecutionException e )
        {
            assertTrue( "Test thrown exception", e.getCause().getMessage().startsWith( "The type parameter has an invalid value: invalid." ) );
        }
    }

    public void testTagType()
        throws Exception
    {
        executeMojo( "tag-plugin-config.xml" );
    }

    public void testTagsType()
        throws Exception
    {
        executeMojo( "tags-plugin-config.xml" );
    }

    public void testDateException()
        throws Exception
    {
        try
        {
            executeMojo( "inv-date-plugin-config.xml" );
        }
        catch ( MojoExecutionException e )
        {
            assertTrue( "Test thrown exception",
                        e.getCause().getCause().getMessage().startsWith( "Please use this date pattern: ") );
        }
    }

    public void testDateType()
        throws Exception
    {
        executeMojo( "date-plugin-config.xml" );
    }

    public void testDatesType()
        throws Exception
    {
        executeMojo( "dates-plugin-config.xml" );
    }

    public void testScmRepositoryWithHost()
        throws Exception
    {
        scmManager = new ScmManagerWithHostStub();

        executeMojo( "hosted-plugin-config.xml" );
    }

    public void testScmRepositoryWithHostFromSettings()
        throws Exception
    {
        scmManager = new ScmManagerWithHostStub();

        executeMojo( "hosted-with-settings-plugin-config.xml" );
    }

    public void testNoScmConnection()
        throws Exception
    {
        try
        {
            executeMojo( "no-scm-plugin-config.xml" );
        }
        catch ( MojoExecutionException e )
        {
            assertEquals( "Test thrown exception", "SCM Connection is not set.",
                          e.getCause().getCause().getCause().getMessage() );
        }
    }

    private void executeMojo( String pluginXml )
        throws Exception
    {
        File pluginXmlFile = new File( getBasedir(), "src/test/plugin-configs/changelog/" + pluginXml );

        ChangeLogReport mojo = (ChangeLogReport)lookupMojo( "changelog", pluginXmlFile );

        assertNotNull( "Mojo found.", mojo );

        this.setVariableValueToObject( mojo, "manager", scmManager );

        mojo.execute();

        File outputXML = (File) getVariableValueFromObject( mojo, "outputXML" );

        String encoding = (String) getVariableValueFromObject( mojo, "outputEncoding" );

        assertTrue( "Test if changelog.xml is created", outputXML.exists() );

        String changelogXml = FileUtils.fileRead( outputXML );

        assertTrue( "Test for xml header", changelogXml.startsWith( "<?xml version=\"1.0\" encoding=\"" +
                    encoding + "\"?>" ) );

        assertTrue( "Test for xml footer", changelogXml.endsWith( "</changelog>" ) );

        File outputDir = (File) getVariableValueFromObject( mojo, "outputDirectory" );

        File outputHtml = new File( outputDir, "changelog.html" );

        renderer( mojo, outputHtml );

        assertTrue( outputHtml.getAbsolutePath() + " not generated!", outputHtml.exists() );

        assertTrue( outputHtml.getAbsolutePath() + " is empty!", outputHtml.length() > 0 );
    }
}
