package org.apache.maven.shared.release.versions;

/*
 * 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.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.codehaus.plexus.util.StringUtils;

public class Version
    implements Comparable<Version>
{
    private final AetherVersion aetherVersion;

    private final MavenArtifactVersion mavenArtifactVersion;

    private final String strVersion;

    private final List<String> digits;

    private String annotation;

    private String annotationRevision;

    private final String buildSpecifier;

    private String annotationSeparator;

    private String annotationRevSeparator;

    private final String buildSeparator;

    private static final int DIGITS_INDEX = 1;

    private static final int ANNOTATION_SEPARATOR_INDEX = 2;

    private static final int ANNOTATION_INDEX = 3;

    private static final int ANNOTATION_REV_SEPARATOR_INDEX = 4;

    private static final int ANNOTATION_REVISION_INDEX = 5;

    private static final int BUILD_SEPARATOR_INDEX = 6;

    private static final int BUILD_SPECIFIER_INDEX = 7;

    private static final String SNAPSHOT_IDENTIFIER = "SNAPSHOT";

    private static final String DIGIT_SEPARATOR_STRING = ".";

    public static final Pattern STANDARD_PATTERN = Pattern.compile( "^((?:\\d+\\.)*\\d+)" // digit(s) and '.' repeated -
                                                                                          // followed by digit (version
                                                                                          // digits 1.22.0, etc)
        + "([-_])?" // optional - or _ (annotation separator)
        + "([a-zA-Z]*)" // alpha characters (looking for annotation - alpha, beta, RC, etc.)
        + "([-_])?" // optional - or _ (annotation revision separator)
        + "(\\d*)" // digits (any digits after rc or beta is an annotation revision)
        + "(?:([-_])?(.*?))?$" ); // - or _ followed everything else (build specifier)

    /* *
     * cmaki 02242009 FIX for non-digit release numbers, e.g. trunk-SNAPSHOT or just SNAPSHOT This alternate pattern
     * supports version numbers like: trunk-SNAPSHOT branchName-SNAPSHOT SNAPSHOT
     */
    public static final Pattern ALTERNATE_PATTERN = Pattern.compile( "^(SNAPSHOT|[a-zA-Z]+[_-]SNAPSHOT)" // for SNAPSHOT
                                                                                                         // releases
                                                                                                         // only
                                                                                                         // (possible
                                                                                                         // versions
                                                                                                         // include:
                                                                                                         // trunk-SNAPSHOT
                                                                                                         // or SNAPSHOT)
    );

    public Version( String version )
        throws VersionParseException
    {
        this.strVersion = version;
        this.aetherVersion = new AetherVersion( version );
        this.mavenArtifactVersion = new MavenArtifactVersion( version );

        // FIX for non-digit release numbers, e.g. trunk-SNAPSHOT or just SNAPSHOT
        Matcher matcher = ALTERNATE_PATTERN.matcher( strVersion );
        // TODO: hack because it didn't support "SNAPSHOT"
        if ( matcher.matches() )
        {
            annotation = null;
            digits = null;
            buildSpecifier = version;
            buildSeparator = null;
            return;
        }

        Matcher m = STANDARD_PATTERN.matcher( strVersion );
        if ( m.matches() )
        {
            digits = parseDigits( m.group( DIGITS_INDEX ) );
            if ( !SNAPSHOT_IDENTIFIER.equals( m.group( ANNOTATION_INDEX ) ) )
            {
                annotationSeparator = m.group( ANNOTATION_SEPARATOR_INDEX );
                annotation = nullIfEmpty( m.group( ANNOTATION_INDEX ) );

                if ( StringUtils.isNotEmpty( m.group( ANNOTATION_REV_SEPARATOR_INDEX ) )
                    && StringUtils.isEmpty( m.group( ANNOTATION_REVISION_INDEX ) ) )
                {
                    // The build separator was picked up as the annotation revision separator
                    buildSeparator = m.group( ANNOTATION_REV_SEPARATOR_INDEX );
                    buildSpecifier = nullIfEmpty( m.group( BUILD_SPECIFIER_INDEX ) );
                }
                else
                {
                    annotationRevSeparator = m.group( ANNOTATION_REV_SEPARATOR_INDEX );
                    annotationRevision = nullIfEmpty( m.group( ANNOTATION_REVISION_INDEX ) );

                    buildSeparator = m.group( BUILD_SEPARATOR_INDEX );
                    buildSpecifier = nullIfEmpty( m.group( BUILD_SPECIFIER_INDEX ) );
                }
            }
            else
            {
                // Annotation was "SNAPSHOT" so populate the build specifier with that data
                buildSeparator = m.group( ANNOTATION_SEPARATOR_INDEX );
                buildSpecifier = nullIfEmpty( m.group( ANNOTATION_INDEX ) );
            }
        }
        else
        {
            throw new VersionParseException( "Unable to parse the version string: \"" + version + "\"" );
        }
    }

    public boolean isSnapshot()
    {
        return ArtifactUtils.isSnapshot( strVersion );
    }

    public String toString()
    {
        return strVersion;
    }

    protected static String getVersionString( Version info, String buildSpecifier, String buildSeparator )
    {
        StringBuilder sb = new StringBuilder();

        if ( info.digits != null )
        {
            sb.append( joinDigitString( info.digits ) );
        }

        if ( StringUtils.isNotEmpty( info.annotation ) )
        {
            sb.append( StringUtils.defaultString( info.annotationSeparator ) );
            sb.append( info.annotation );
        }

        if ( StringUtils.isNotEmpty( info.annotationRevision ) )
        {
            if ( StringUtils.isEmpty( info.annotation ) )
            {
                sb.append( StringUtils.defaultString( info.annotationSeparator ) );
            }
            else
            {
                sb.append( StringUtils.defaultString( info.annotationRevSeparator ) );
            }
            sb.append( info.annotationRevision );
        }

        if ( StringUtils.isNotEmpty( buildSpecifier ) )
        {
            sb.append( StringUtils.defaultString( buildSeparator ) );
            sb.append( buildSpecifier );
        }

        return sb.toString();
    }

    /**
     * Simply joins the items in the list with "." period
     * 
     * @param digits
     */
    protected static String joinDigitString( List<String> digits )
    {
        return digits != null ? StringUtils.join( digits.iterator(), DIGIT_SEPARATOR_STRING ) : null;
    }

    /**
     * Splits the string on "." and returns a list containing each digit.
     * 
     * @param strDigits
     */
    private List<String> parseDigits( String strDigits )
    {
        return Arrays.asList( StringUtils.split( strDigits, DIGIT_SEPARATOR_STRING ) );
    }

    private static String nullIfEmpty( String s )
    {
        return StringUtils.isEmpty( s ) ? null : s;
    }

    public List<String> getDigits()
    {
        return digits;
    }

    public String getAnnotation()
    {
        return annotation;
    }

    public String getAnnotationRevSeparator()
    {
        return annotationRevSeparator;
    }

    public String getAnnotationRevision()
    {
        return annotationRevision;
    }

    public String getBuildSeparator()
    {
        return buildSeparator;
    }

    public String getBuildSpecifier()
    {
        return buildSpecifier;
    }

    /**
     * @throws VersionComparisonConflictException if {@link org.eclipse.aether.version.Version} and
     *             {@link ArtifactVersion} give different results
     */
    public int compareTo( Version other )
        throws VersionComparisonConflictException
    {
        int aetherComparisonResult = this.aetherVersion.compareTo( other.aetherVersion );
        int mavenComparisonResult = this.mavenArtifactVersion.compareTo( other.mavenArtifactVersion );

        if ( aetherComparisonResult < 0 && mavenComparisonResult < 0 )
        {
            return -1;
        }
        else if ( aetherComparisonResult == 0 && mavenComparisonResult == 0 )
        {
            return 0;
        }
        else if ( aetherComparisonResult > 0 && mavenComparisonResult > 0 )
        {
            return 1;
        }
        else
        {
            throw new VersionComparisonConflictException( this.strVersion, other.strVersion, aetherComparisonResult,
                                                          mavenComparisonResult );
        }
    }

}
