package org.apache.maven.plugins.checkstyle;

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

import org.codehaus.plexus.util.StringUtils;

import com.puppycrawl.tools.checkstyle.api.AuditEvent;

/**
 * Tooling for Checkstyle rules conventions: names, categories.
 *
 * @author Hervé Boutemy
 * @since 2.13
 */
public final class RuleUtil
{
    private RuleUtil()
    {
        // hide utility class constructor
    }
    
    private static final String CHECKSTYLE_PACKAGE = "com.puppycrawl.tools.checkstyle.checks";

    /**
     * Get the rule name from an audit event.
     *
     * @param event the audit event
     * @return the rule name, which is the class name without package and removed eventual "Check" suffix
     */
    public static String getName( AuditEvent event )
    {
        return getName( event.getSourceName() );
    }
    /**
     * Get the rule name from an audit event source name.
     *
     * @param eventSrcName the audit event source name
     * @return the rule name, which is the class name without package and removed eventual "Check" suffix
     */
    public static String getName( String eventSrcName )
    {
        if ( eventSrcName == null )
        {
            return null;
        }

        if ( eventSrcName.endsWith( "Check" ) )
        {
            eventSrcName = eventSrcName.substring( 0, eventSrcName.length() - 5 );
        }

        return eventSrcName.substring( eventSrcName.lastIndexOf( '.' ) + 1 );
    }

    /**
     * Get the rule category from an audit event.
     *
     * @param event the audit event
     * @return the rule category, which is the last package name or "misc" or "extension"
     */
    public static String getCategory( AuditEvent event )
    {
        return getCategory( event.getSourceName() );
    }

    /**
     * Get the rule category from an audit event source name.
     *
     * @param eventSrcName the audit event source name
     * @return the rule category, which is the last package name or "misc" or "extension"
     */
    public static String getCategory( String eventSrcName )
    {
        if ( eventSrcName == null )
        {
            return null;
        }

        int end = eventSrcName.lastIndexOf( '.' );
        eventSrcName = end == -1 ? eventSrcName : eventSrcName.substring( 0,  end );

        if ( CHECKSTYLE_PACKAGE.equals( eventSrcName ) )
        {
            return "misc";
        }
        else if ( !eventSrcName.startsWith( CHECKSTYLE_PACKAGE ) )
        {
            return "extension";
        }

        return eventSrcName.substring( eventSrcName.lastIndexOf( '.' ) + 1 );
    }

    public static List<Matcher> parseMatchers( String[] specs )
    {
        List<Matcher> matchers = new ArrayList<>();
        for ( String spec : specs )
        {
            if ( StringUtils.isBlank( spec ) )
            {
                continue;
            }
            spec = spec.trim();
            Matcher matcher;
            if ( Character.isUpperCase( spec.charAt( 0 ) ) )
            {
                // spec starting with uppercase is a rule name
                matcher = new RuleMatcher( spec );
            }
            else if ( "misc".equals( spec ) )
            {
                // "misc" is a special case
                matcher = new PackageMatcher( CHECKSTYLE_PACKAGE );
            }
            else if ( "extension".equals( spec ) )
            {
                // "extension" is a special case
                matcher = new ExtensionMatcher();
            }
            else if ( !spec.contains( "." ) )
            {
                matcher = new PackageMatcher( CHECKSTYLE_PACKAGE + '.' + spec );
            }
            else
            {
                // by default, spec is a package name
                matcher = new PackageMatcher( spec );
            }
            matchers.add( matcher );
        }
        return matchers;
    }

    /**
     * Audit event source name matcher.
     */
    public interface Matcher
    {
        /**
         * Does the event source name match?
         * @param eventSrcName the event source name
         * @return boolean
         */
        boolean match( String eventSrcName );
    }

    private static class RuleMatcher
        implements Matcher
    {
        private final String rule;

        RuleMatcher( String rule )
        {
            this.rule = rule;
        }

        public boolean match( String eventSrcName )
        {
            return rule.equals( getName( eventSrcName ) );
        }
    }

    private static class PackageMatcher
        implements Matcher
    {
        private final String packageName;

        PackageMatcher( String packageName )
        {
            this.packageName = packageName;
        }

        public boolean match( String eventSrcName )
        {
            return eventSrcName.startsWith( packageName )
                && !eventSrcName.substring( packageName.length() + 1 ).contains( "." );
        }
    }

    /**
     * An extension does not start with Checkstyle package.
     */
    private static class ExtensionMatcher
        implements Matcher
    {
        public boolean match( String eventSrcName )
        {
            return !eventSrcName.startsWith( CHECKSTYLE_PACKAGE );
        }
    }
}
