package org.apache.maven.plugin.pmd;

/*
 * 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.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.pmd.model.PmdErrorDetail;
import org.apache.maven.plugin.pmd.model.PmdFile;
import org.apache.maven.plugin.pmd.model.Violation;
import org.apache.maven.plugin.pmd.model.io.xpp3.PmdXpp3Reader;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 * Fail the build if there were any PMD violations in the source code.
 *
 * @version $Id$
 * @since 2.0
 */
@Mojo( name = "check", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true )
@Execute( goal = "pmd" )
public class PmdViolationCheckMojo
    extends AbstractPmdViolationCheckMojo<Violation>
{
    /**
     * What priority level to fail the build on. Failures at or above this level will stop the build. Anything below
     * will be warnings and will be displayed in the build output if verbose=true. Note: Minimum Priority = 5 Maximum
     * Priority = 0
     */
    @Parameter( property = "pmd.failurePriority", defaultValue = "5", required = true )
    private int failurePriority;

    /**
     * Skip the PMD checks. Most useful on the command line via "-Dpmd.skip=true".
     */
    @Parameter( property = "pmd.skip", defaultValue = "false" )
    private boolean skip;

    private final Map<String, Set<String>> excludeFromFailureClasses = new HashMap<String, Set<String>>();

    /**
     * {@inheritDoc}
     */
    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        if ( !skip )
        {
            executeCheck( "pmd.xml", "violation", "PMD violation", failurePriority );
        }
    }

    @Override
    protected void loadExcludeFromFailuresData( final String excludeFromFailureFile )
        throws MojoExecutionException
    {
        File file = new File( excludeFromFailureFile );
        if ( !file.exists() )
        {
            return;
        }
        final Properties props = new Properties();
        FileInputStream fileInputStream = null;
        try
        {
            fileInputStream = new FileInputStream( new File( excludeFromFailureFile ) );
            props.load( fileInputStream );
        }
        catch ( final IOException e )
        {
            throw new MojoExecutionException( "Cannot load properties file " + excludeFromFailureFile, e );
        }
        finally
        {
            IOUtil.close( fileInputStream );
        }
        for ( final Entry<Object, Object> propEntry : props.entrySet() )
        {
            final Set<String> excludedRuleSet = new HashSet<String>();
            final String className = propEntry.getKey().toString();
            final String[] excludedRules = propEntry.getValue().toString().split( "," );
            for ( final String excludedRule : excludedRules )
            {
                excludedRuleSet.add( excludedRule.trim() );
            }
            excludeFromFailureClasses.put( className, excludedRuleSet );
        }
    }

    @Override
    protected boolean isExcludedFromFailure( final Violation errorDetail )
    {
        final String className = extractClassName( errorDetail );
        final Set<String> excludedRuleSet = excludeFromFailureClasses.get( className );
        return excludedRuleSet != null && excludedRuleSet.contains( errorDetail.getRule() );
    }

    private String extractClassName( final Violation errorDetail )
    {
        // for some reason, some violations don't contain the package name, so we have to guess the full class name
        if ( errorDetail.getViolationPackage() != null && errorDetail.getViolationClass() != null )
        {
            return errorDetail.getViolationPackage() + "." + errorDetail.getViolationClass();
        }
        else
        {
            final String fileName = errorDetail.getFileName();
            final int javaIdx = fileName.indexOf( "\\java\\" );
            return fileName.substring( javaIdx >= 0 ? javaIdx + 6 : 0, fileName.length() - 5 ).replace( '\\', '.' );
        }
    }

    /**
     * {@inheritDoc}
     */
    protected void printError( Violation item, String severity )
    {

        StringBuilder buff = new StringBuilder( 100 );
        buff.append( "PMD " ).append( severity ).append( ": " );
        if ( item.getViolationClass() != null )
        {
            if ( item.getViolationPackage() != null )
            {
                buff.append( item.getViolationPackage() );
                buff.append( "." );
            }
            buff.append( item.getViolationClass() );
        }
        else
        {
            buff.append( item.getFileName() );
        }
        buff.append( ":" );
        buff.append( item.getBeginline() );
        buff.append( " Rule:" ).append( item.getRule() );
        buff.append( " Priority:" ).append( item.getPriority() );
        buff.append( " " ).append( item.getText() ).append( "." );

        this.getLog().info( buff.toString() );
    }

    @Override
    protected List<Violation> getErrorDetails( File pmdFile )
        throws XmlPullParserException, IOException
    {
        PmdXpp3Reader reader = new PmdXpp3Reader();
        PmdErrorDetail details = reader.read( new FileReader( pmdFile ), false );

        List<Violation> violations = new ArrayList<Violation>();
        for ( PmdFile file : details.getFiles() )
        {
            String fullPath = file.getName();

            for ( Violation violation : file.getViolations() )
            {
                violation.setFileName( getFilename( fullPath, violation.getViolationPackage() ) );
                violations.add( violation );
            }
        }
        return violations;
    }

    @Override
    protected int getPriority( Violation errorDetail )
    {
        return errorDetail.getPriority();
    }

    @Override
    protected ViolationDetails<Violation> newViolationDetailsInstance()
    {
        return new ViolationDetails<Violation>();
    }

    private String getFilename( String fullpath, String pkg )
    {
        int index = fullpath.lastIndexOf( File.separatorChar );

        while ( StringUtils.isNotEmpty( pkg ) )
        {
            index = fullpath.substring( 0, index ).lastIndexOf( File.separatorChar );

            int dot = pkg.indexOf( '.' );

            if ( dot < 0 )
            {
                break;
            }
            pkg = pkg.substring( dot + 1 );
        }

        return fullpath.substring( index + 1 );
    }
}