package org.apache.maven.plugins.enforcer;

/*
 * 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.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.enforcer.rule.api.EnforcerRule;
import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
import org.apache.maven.plugin.logging.Log;
import org.codehaus.plexus.util.StringUtils;

/**
 * Contains the common code to compare a version against a version range.
 *
 * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
 */
public abstract class AbstractVersionEnforcer
    extends AbstractStandardEnforcerRule
{

    /**
     * Specify the required version. Some examples are:
     * <ul>
     * <li><code>2.0.4</code> Version 2.0.4 and higher (different from Maven meaning)</li>
     * <li><code>[2.0,2.1)</code> Versions 2.0 (included) to 2.1 (not included)</li>
     * <li><code>[2.0,2.1]</code> Versions 2.0 to 2.1 (both included)</li>
     * <li><code>[2.0.5,)</code> Versions 2.0.5 and higher</li>
     * <li><code>(,2.0.5],[2.1.1,)</code> Versions up to 2.0.5 (included) and 2.1.1 or higher</li>
     * </ul>
     * 
     * @see {@link #setVersion(String)}
     * @see {@link #getVersion()}
     */
    private String version;

    /**
     * Compares the specified version to see if it is allowed by the defined version range.
     *
     * @param log the log
     * @param variableName name of variable to use in messages (Example: "Maven" or "Java" etc).
     * @param requiredVersionRange range of allowed versions.
     * @param actualVersion the version to be checked.
     * @throws EnforcerRuleException the enforcer rule exception
     */
    // CHECKSTYLE_OFF: LineLength
    public void enforceVersion( Log log, String variableName, String requiredVersionRange, ArtifactVersion actualVersion )
        throws EnforcerRuleException
    // CHECKSTYLE_ON: LineLength
    {
        if ( StringUtils.isEmpty( requiredVersionRange ) )
        {
            throw new EnforcerRuleException( variableName + " version can't be empty." );
        }
        else
        {

            VersionRange vr;
            String msg = "Detected " + variableName + " Version: " + actualVersion;

            // short circuit check if the strings are exactly equal
            if ( actualVersion.toString().equals( requiredVersionRange ) )
            {
                log.debug( msg + " is allowed in the range " + requiredVersionRange + "." );
            }
            else
            {
                try
                {
                    vr = VersionRange.createFromVersionSpec( requiredVersionRange );

                    if ( containsVersion( vr, actualVersion ) )
                    {
                        log.debug( msg + " is allowed in the range " + requiredVersionRange + "." );
                    }
                    else
                    {
                        String message = getMessage();

                        if ( StringUtils.isEmpty( message ) )
                        {
                            message = msg + " is not in the allowed range " + vr + ".";
                        }

                        throw new EnforcerRuleException( message );
                    }
                }
                catch ( InvalidVersionSpecificationException e )
                {
                    throw new EnforcerRuleException( "The requested " + variableName + " version "
                        + requiredVersionRange + " is invalid.", e );
                }
            }
        }
    }

    /**
     * Copied from Artifact.VersionRange. This is tweaked to handle singular ranges properly. Currently the default
     * containsVersion method assumes a singular version means allow everything. This method assumes that "2.0.4" ==
     * "[2.0.4,)"
     *
     * @param allowedRange range of allowed versions.
     * @param theVersion the version to be checked.
     * @return true if the version is contained by the range.
     */
    public static boolean containsVersion( VersionRange allowedRange, ArtifactVersion theVersion )
    {
        ArtifactVersion recommendedVersion = allowedRange.getRecommendedVersion();
        if ( recommendedVersion == null )
        {
            return allowedRange.containsVersion( theVersion );
        }
        else
        {
            // only singular versions ever have a recommendedVersion
            @SuppressWarnings( "unchecked" )
            int compareTo = recommendedVersion.compareTo( theVersion );
            return ( compareTo <= 0 );
        }
    }

    @Override
    public String getCacheId()
    {
        if ( StringUtils.isNotEmpty( version ) )
        {
            // return the hashcodes of the parameter that matters
            return "" + version.hashCode();
        }
        else
        {
            return "0";
        }

    }

    @Override
    public boolean isCacheable()
    {
        // the maven version is not going to change between projects in the same build.
        return true;
    }

    @Override
    public boolean isResultValid( EnforcerRule theCachedRule )
    {
        // i will always return the hash of the parameters as my id. If my parameters are the same, this
        // rule must always have the same result.
        return true;
    }

    /**
     * Gets the required version.
     *
     * @return the required version
     */
    public final String getVersion()
    {
        return this.version;
    }

    /**
     * Specify the required version. Some examples are:
     * <ul>
     * <li><code>2.0.4</code> Version 2.0.4 and higher (different from Maven meaning)</li>
     * <li><code>[2.0,2.1)</code> Versions 2.0 (included) to 2.1 (not included)</li>
     * <li><code>[2.0,2.1]</code> Versions 2.0 to 2.1 (both included)</li>
     * <li><code>[2.0.5,)</code> Versions 2.0.5 and higher</li>
     * <li><code>(,2.0.5],[2.1.1,)</code> Versions up to 2.0.5 (included) and 2.1.1 or higher</li>
     * </ul>
     *
     * @param theVersion the required version to set
     */
    public final void setVersion( String theVersion )
    {
        this.version = theVersion;
    }

}
