/******************************************************************************
 * Copyright (c) 2010 Oracle
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Konstantin Komissarchik - initial implementation and ongoing maintenance
 ******************************************************************************/

package org.eclipse.wst.common.project.facet.core.util.internal;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.project.facet.core.IVersion;
import org.eclipse.wst.common.project.facet.core.IVersionExpr;
import org.eclipse.wst.common.project.facet.core.internal.FacetCorePlugin;
import org.eclipse.wst.common.project.facet.core.internal.ProjectFacet;

/**
 * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
 */

public final class VersionExpr<T extends IVersion>

    implements IVersionExpr
    
{
    private static final int SM1_START = 0;
    private static final int SM1_PARSING_START_VERSION = 1;
    private static final int SM1_PARSING_END_VERSION = 2;
    private static final int SM1_FINISHED_RANGE_INCLUSIVE = 3;
    private static final int SM1_FINISHED_RANGE_EXCLUSIVE = 4;
    private static final int SM1_PARSING_WILDCARD = 5;
    
    private static final int SM2_VERSION_START = 0;
    private static final int SM2_VERSION_CONTINUING = 1;
    private static final int SM2_ESCAPE = 2;
    
    private final Versionable<T> versionable;
    private final String originalExprString;
    private final List<ISubExpr> subexprs;
    private final String usedInPlugin;
    
    @SuppressWarnings( "unchecked" )
    public VersionExpr( final Object versionable,
                        final String expr,
                        final String usedInPlugin )
    
        throws CoreException
        
    {
        this( (Versionable<T>) versionable, expr, usedInPlugin );
    }
    
    public VersionExpr( final Versionable<T> versionable,
                        final String expr,
                        final String usedInPlugin )
    
        throws CoreException
        
    {
        this.versionable = versionable;
        this.originalExprString = expr;
        this.subexprs = new ArrayList<ISubExpr>();
        this.usedInPlugin = usedInPlugin;
        
        int state = SM1_START;
        Range range = null;
        boolean usingDeprecatedSyntax = false;
        
        for( MutableInteger position = new MutableInteger(); 
             position.value < expr.length(); position.value++ )
        {
            final char ch = expr.charAt( position.value );
            
            switch( state )
            {
                case SM1_START:
                {
                    if( ch == '[' )
                    {
                        range = new Range();
                        range.includesStartVersion = true;
                        state = SM1_PARSING_START_VERSION;
                    }
                    else if( ch == '(' )
                    {
                        range = new Range();
                        range.includesStartVersion = false;
                        state = SM1_PARSING_START_VERSION;
                    }
                    else if( ch == '*' )
                    {
                        this.subexprs.add( new Wildcard() );
                        state = SM1_PARSING_WILDCARD;
                    }
                    else if( ch == ' ' || ch == ',' )
                    {
                        // ignore
                    }
                    else
                    {
                        final StringBuffer buf = new StringBuffer();
                        final int exitState = parseVersion( expr, position, buf );
                        
                        if( exitState == SM1_START )
                        {
                            final String vstr = buf.toString();
                            final Range r = new Range();
                            
                            if( vstr.startsWith( ">=" ) ) //$NON-NLS-1$
                            {
                                r.startVersion = parseVersion( vstr.substring( 2 ) );
                                r.includesStartVersion = true;
                                usingDeprecatedSyntax = true;
                            }
                            else if( vstr.startsWith( ">" ) ) //$NON-NLS-1$
                            {
                                r.startVersion = parseVersion( vstr.substring( 1 ) );
                                r.includesStartVersion = false;
                                usingDeprecatedSyntax = true;
                            }
                            else if( vstr.startsWith( "<=" ) ) //$NON-NLS-1$
                            {
                                r.endVersion = parseVersion( vstr.substring( 2 ) );
                                r.includesEndVersion = true;
                                usingDeprecatedSyntax = true;
                            }
                            else if( vstr.startsWith( "<" ) ) //$NON-NLS-1$
                            {
                                r.endVersion = parseVersion( vstr.substring( 1 ) );
                                r.includesEndVersion = false;
                                usingDeprecatedSyntax = true;
                            }
                            else
                            {
                                r.startVersion = parseVersion( vstr );
                                r.includesStartVersion = true;
                                r.endVersion = r.startVersion;
                                r.includesEndVersion = true;
                            }
                            
                            this.subexprs.add( r );
                        }
                        else if( exitState == SM1_FINISHED_RANGE_INCLUSIVE ||
                                 exitState == SM1_FINISHED_RANGE_EXCLUSIVE )
                        {
                            range = new Range();
                            range.endVersion = parseVersion( buf.toString() );
                            state = exitState;
                            position.value--;
                        }
                        else
                        {
                            throw createInvalidVersionExprException( expr );
                        }
                    }
                    
                    break;
                }
                case SM1_PARSING_START_VERSION:
                {
                    final StringBuffer buf = new StringBuffer();
                    final int exitState = parseVersion( expr, position, buf );

                    if( exitState == SM1_START )
                    {
                        range.startVersion = parseVersion( buf.toString() );
                        this.subexprs.add( range );
                        range = null;
                        state = exitState;
                    }
                    else if( exitState == SM1_PARSING_END_VERSION )
                    {
                        range.startVersion = parseVersion( buf.toString() );
                        state = exitState;
                    }
                    else
                    {
                        throw createInvalidVersionExprException( expr );
                    }
                    
                    break;
                }
                case SM1_PARSING_END_VERSION:
                {
                    final StringBuffer buf = new StringBuffer();
                    final int exitState = parseVersion( expr, position, buf );
                    
                    if( exitState == SM1_FINISHED_RANGE_INCLUSIVE ||
                        exitState == SM1_FINISHED_RANGE_EXCLUSIVE )
                    {
                        range.endVersion = parseVersion( buf.toString() );
                        state = exitState;
                        position.value--;
                    }
                    else
                    {
                        throw createInvalidVersionExprException( expr );
                    }
                    
                    break;
                }
                case SM1_FINISHED_RANGE_INCLUSIVE:
                case SM1_FINISHED_RANGE_EXCLUSIVE:
                {
                    range.includesEndVersion 
                        = ( state == SM1_FINISHED_RANGE_INCLUSIVE );
                    
                    this.subexprs.add( range );
                    range = null;
                    
                    state = SM1_START;
                    
                    break;
                }
                case SM1_PARSING_WILDCARD:
                {
                    if( ch == ' ' )
                    {
                        // ignore
                    }
                    else if( ch == ',' )
                    {
                        state = SM1_START;
                    }
                    else
                    {
                        throw createInvalidVersionExprException( expr );
                    }
                }
                default:
                {
                    throw new IllegalStateException();
                }
            }
        }
        
        // Report the use of deprecated syntax.
        
        if( usingDeprecatedSyntax )
        {
            final StringBuilder msg = new StringBuilder();
            final String nl = System.getProperty( "line.separator" ); //$NON-NLS-1$
            
            msg.append( Resources.depMessage );
            msg.append( nl );
            msg.append( nl );
            msg.append( NLS.bind( Resources.depExpression, this.originalExprString ) );
            msg.append( nl );
            
            if( this.versionable instanceof ProjectFacet )
            {
                msg.append( NLS.bind( Resources.depUsedWithFacet, this.versionable.toString() ) );
            }
            else
            {
                msg.append( NLS.bind( Resources.depUsedWithRuntimeComponentType, this.versionable.toString() ) );
            }
            
            if( this.usedInPlugin != null )
            {
                msg.append( nl );
                msg.append( NLS.bind( Resources.depUsedInBundle, this.usedInPlugin ) );
            }
            
            FacetCorePlugin.logWarning( msg.toString(), true );
        }
    }
    
    private int parseVersion( final String str,
                              final MutableInteger position,
                              final StringBuffer version )
    
        throws CoreException
        
    {
        int localState = SM2_VERSION_START;
        int exitState = -1;
        
        for( ; exitState == -1 && position.value < str.length(); 
             position.value++ )
        {
            final char ch = str.charAt( position.value );
            
            switch( localState )
            {
                case SM2_VERSION_START:
                {
                    if( ch == '[' || ch == '(' || ch == ']' || ch == ')' ||
                        ch == '-' || ch == ',' )
                    {
                        throw createInvalidVersionExprException( str );
                    }
                    else if( ch == '\\' )
                    {
                        localState = SM2_ESCAPE;
                    }
                    else if( ch == ' ' )
                    {
                        // ignore
                    }
                    else
                    {
                        version.append( ch );
                        localState = SM2_VERSION_CONTINUING;
                    }
                    
                    break;
                }
                case SM2_VERSION_CONTINUING:
                {
                    if( ch == '[' || ch == '(' )
                    {
                        throw createInvalidVersionExprException( str );
                    }
                    else if( ch == '\\' )
                    {
                        localState = SM2_ESCAPE;
                    }
                    else if( ch == ',' )
                    {
                        exitState = SM1_START;
                    }
                    else if( ch == '-' )
                    {
                        exitState = SM1_PARSING_END_VERSION;
                    }
                    else if( ch == ']' )
                    {
                        exitState = SM1_FINISHED_RANGE_INCLUSIVE;
                    }
                    else if( ch == ')' )
                    {
                        exitState = SM1_FINISHED_RANGE_EXCLUSIVE;
                    }
                    else if( ch == ' ' )
                    {
                        // ignore
                    }
                    else
                    {
                        version.append( ch );
                    }
                    
                    break;
                }
                case SM2_ESCAPE:
                {
                    version.append( ch );
                    break;
                }
                default:
                {
                    throw new IllegalStateException();
                }
            }
        }
        
        position.value--;
        
        if( exitState != -1 )
        {
            return exitState;
        }
        else
        {
            if( localState == SM2_VERSION_CONTINUING )
            {
                // Expected end of input.
                
                return SM1_START;
            }
            else
            {
                // Unexpected end of input.
                
                throw createInvalidVersionExprException( str );
            }
        }
    }
    
    private IVersion parseVersion( final String str )
    {
        if( this.versionable.hasVersion( str ) )
        {
            return this.versionable.getVersion( str );
        }
        else
        {
            return new UnknownVersion<T>( this.versionable, str );
        }
    }
    
    public boolean check( final IVersion ver )
    {
        for( ISubExpr subexpr : this.subexprs )
        {
            if( subexpr.evaluate( ver ) )
            {
                return true;
            }
        }
        
        return false;
    }
    
    public boolean evaluate( final String ver )
    {
        return check( parseVersion( ver ) );
    }
    
    public boolean isSingleVersionMatch()
    {
        if( this.subexprs.size() == 1 )
        {
            final ISubExpr subExpr = this.subexprs.get( 0 );
            
            if( subExpr instanceof Range )
            {
                final Range range = (Range) subExpr;
                
                if( range.startVersion.equals( range.endVersion ) &&
                    range.includesStartVersion == range.includesEndVersion == true )
                {
                    return true;
                }
            }
        }
        
        return false;
    }

    public boolean isSimpleAllowNewer()
    {
        if( this.subexprs.size() == 1 )
        {
            final ISubExpr subExpr = this.subexprs.get( 0 );
            
            if( subExpr instanceof Range )
            {
                final Range range = (Range) subExpr;
            
                if( range.startVersion != null && range.endVersion == null &&
                    range.includesStartVersion  )
                {
                    return true;
                }
            }
        }
        
        return false;
    }
    
    public boolean isWildcard()
    {
        return this.subexprs.size() == 1 && 
               this.subexprs.get( 0 ) instanceof Wildcard;
    }
    
    public String getFirstVersion()
    {
        if( isSingleVersionMatch() || isSimpleAllowNewer() )
        {
            final Range range = (Range) this.subexprs.get( 0 );
            return range.startVersion.getVersionString();
        }
        else
        {
            throw new IllegalStateException();
        }
    }
    
    public String toString()
    {
        final StringBuffer buf = new StringBuffer();
        
        for( ISubExpr subexpr : this.subexprs )
        {
            if( buf.length() > 0 ) buf.append( ',' );
            buf.append( subexpr.toString() );
        }
        
        return buf.toString();
    }
    
    public String toDisplayString()
    {
        if( this.subexprs.size() == 1 )
        {
            final ISubExpr subexpr = this.subexprs.get( 0 );
            
            if( subexpr instanceof Range )
            {
                final Range r = (Range) subexpr;
                
                if( r.isSingleVersion() )
                {
                    return r.startVersion.getVersionString();
                }
                else if( r.endVersion == null && r.includesStartVersion )
                {
                    return NLS.bind( Resources.versionOrNewer, 
                                     r.startVersion.getVersionString() );
                }
            }
        }

        boolean onlySingleVersions = true;
        
        for( ISubExpr subexpr : this.subexprs )
        {
            if( ! ( subexpr instanceof Range ) || 
                ! ( (Range) subexpr ).isSingleVersion() )
            {
                onlySingleVersions = false;
                break;
            }
        }
        
        if( onlySingleVersions )
        {
            final StringBuffer buf = new StringBuffer();

            for( Iterator<ISubExpr> itr = this.subexprs.iterator(); itr.hasNext(); )
            {
                final Range r = (Range) itr.next();
                
                if( buf.length() > 0 )
                {
                    if( itr.hasNext() )
                    {
                        buf.append( ", " ); //$NON-NLS-1$
                    }
                    else
                    {
                        buf.append( " or " ); //$NON-NLS-1$
                    }
                }
                
                buf.append( r.startVersion.getVersionString() );
            }
            
            return buf.toString();
        }
        
        return toString();
    }
    
    private static CoreException createInvalidVersionExprException( final String str )
    {
        final String msg
            = NLS.bind( Resources.invalidVersionExpr, str );
    
        final IStatus st = FacetCorePlugin.createErrorStatus( msg );
    
        return new CoreException( st );
    }
    
    private static interface ISubExpr
    {
        boolean evaluate( IVersion version );
    }
    
    private static final class Range
    
        implements ISubExpr
        
    {
        public IVersion startVersion = null;
        public boolean includesStartVersion = false;
        public IVersion endVersion = null;
        public boolean includesEndVersion = false;
        
        public boolean isSingleVersion()
        {
            return this.startVersion.equals( this.endVersion ) &&
                   this.includesStartVersion == this.includesEndVersion == true;
        }
        
        @SuppressWarnings( "unchecked" )
        public boolean evaluate( final IVersion version )
        {
            if( this.startVersion != null )
            {
                final int res = version.compareTo( this.startVersion );
                
                if( ! ( res > 0 || ( res == 0 && this.includesStartVersion ) ) )
                {
                    return false;
                }
            }
            
            if( this.endVersion != null )
            {
                final int res = version.compareTo( this.endVersion );
                
                if( ! ( res < 0 || ( res == 0 && this.includesEndVersion ) ) )
                {
                    return false;
                }
            }
            
            return true;
        }
        
        public String toString()
        {
            if( this.startVersion.equals( this.endVersion ) &&
                this.includesStartVersion == this.includesEndVersion == true )
            {
                return this.startVersion.getVersionString();
            }
            else
            {
                final StringBuffer buf = new StringBuffer();
                
                if( this.startVersion != null )
                {
                    buf.append( this.includesStartVersion ? '[' : '(' );
                    buf.append( this.startVersion.getVersionString() );
                }
                
                if( this.endVersion != null )
                {
                    if( buf.length() != 0 )
                    {
                        buf.append( '-' );
                    }
                    
                    buf.append( this.endVersion.getVersionString() );
                    buf.append( this.includesEndVersion ? ']' : ')' );
                }
                
                return buf.toString();
            }
        }
    }
    
    private static final class Wildcard
    
        implements ISubExpr
        
    {
        public boolean evaluate( final IVersion version )
        {
            return true;
        }
        
        public String toString()
        {
            return IVersionExpr.WILDCARD_SYMBOL;
        }
    }
    
    private static final class MutableInteger
    {
        public int value = 0;
    }
    
    private static final class Resources
    
        extends NLS
        
    {
        public static String invalidVersionExpr;
        public static String depMessage;
        public static String depExpression;
        public static String depUsedInBundle;
        public static String depUsedWithFacet;
        public static String depUsedWithRuntimeComponentType;
        public static String versionOrNewer;
        
        static
        {
            initializeMessages( VersionExpr.class.getName(), Resources.class );
        }
    }

}
