/******************************************************************************
 * Copyright (c) 2008 BEA Systems, Inc.
 * 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.internal;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.project.facet.core.IActionDefinition;
import org.eclipse.wst.common.project.facet.core.IConstraint;
import org.eclipse.wst.common.project.facet.core.IGroup;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
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.IFacetedProject.Action;
import org.eclipse.wst.common.project.facet.core.util.internal.Versionable;

/**
 * The implementation of the <code>IProjectFacetVersion</code> interface.
 * 
 * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
 */

public final class ProjectFacetVersion 

    implements IProjectFacetVersion
    
{
    private ProjectFacet facet;
    private String version;
    private final Set<String> aliases;
    private final Set<String> aliasesReadOnly;
    private IConstraint constraint;
    private String plugin;
    private Map<IProjectFacetVersion,Integer> compTable = Collections.emptyMap();
    private final Map<String,Object> properties;
    private final Map<String,Object> propertiesReadOnly;
    
    ProjectFacetVersion() 
    {
        this.aliases = new HashSet<String>();
        this.aliasesReadOnly = Collections.unmodifiableSet( this.aliases );
        this.properties = new HashMap<String,Object>();
        this.propertiesReadOnly = Collections.unmodifiableMap( this.properties );
    }
    
    public IProjectFacet getProjectFacet() 
    {
        return this.facet;
    }
    
    void setProjectFacet( final ProjectFacet facet )
    {
        this.facet = facet;
    }

    public String getVersionString() 
    {
        return this.version;
    }
    
    void setVersionString( final String version )
    {
        this.version = version;
    }
    
    public Set<String> getAliases()
    {
        return this.aliasesReadOnly;
    }
    
    void addAlias( final String alias )
    {
        this.aliases.add( alias );
    }
    
    public Versionable<IProjectFacetVersion> getVersionable()
    {
        return this.facet;
    }

    public IConstraint getConstraint()
    {
        if( this.constraint == null )
        {
            this.constraint = new Constraint( this, IConstraint.Type.AND, new Object[ 0 ] );
        }
        
        return this.constraint;
    }
    
    void setConstraint( final IConstraint constraint )
    {
        this.constraint = constraint;
    }
    
    public String getPluginId()
    {
        return this.plugin;
    }
    
    void setPluginId( final String plugin )
    {
        this.plugin = plugin;
    }
    
    void setComparisonTable( final Map<IProjectFacetVersion,Integer> compTable )
    {
        this.compTable = compTable;
    }
    
    public boolean supports( final Set<IProjectFacetVersion> base,
                             final Action.Type type )
    {
        try
        {
            return ( getActionDefinitionInternal( base, type ) != null );
        }
        catch( CoreException e )
        {
            FacetCorePlugin.log( e );
            return false;
        }
    }
    
    /**
     * @deprecated
     */
    
    public boolean supports( final Action.Type type )
    {
        try
        {
            return getActionDefinition( type ) != null;
        }
        catch( CoreException e )
        {
            FacetCorePlugin.log( e );
            return false;
        }
    }
    
    public Set<IActionDefinition> getActionDefinitions()
    {
        return this.facet.getActionDefinitions( this );
    }
    
    public Set<IActionDefinition> getActionDefinitions( final Action.Type type )
    {
        final Set<IActionDefinition> result = new HashSet<IActionDefinition>();
        
        for( IActionDefinition def : getActionDefinitions() )
        {
            if( def.getActionType() == type )
            {
                result.add( def );
            }
        }

        if( result.size() > 1 && type != Action.Type.VERSION_CHANGE )
        {
            final String msg
                = Resources.bind( Resources.multipleActionDefinitions,
                                  this.facet.getId(), this.version,
                                  type.toString() );
            
            FacetCorePlugin.logWarning( msg, true );
        }
        
        return result;
    }
    
    public IActionDefinition getActionDefinition( final Set<IProjectFacetVersion> base,
                                                  final Action.Type type )
    
        throws CoreException
        
    {
        final IActionDefinition def = getActionDefinitionInternal( base, type );
        
        if( def == null )
        {
            final String msg 
                = NLS.bind( Resources.actionNotSupported, toString(), 
                            type.toString() );
            
            throw new CoreException( FacetCorePlugin.createErrorStatus( msg ) );
        }
        
        return def;
    }
    
    private IActionDefinition getActionDefinitionInternal( final Set<IProjectFacetVersion> base,
                                                           final Action.Type type )
    
        throws CoreException
        
    {
        final Set<IActionDefinition> definitions = getActionDefinitions( type );
        
        if( definitions.size() > 0 )
        {
            if( type == Action.Type.VERSION_CHANGE )
            {
                IProjectFacetVersion fromVersion = null;
                
                for( IProjectFacetVersion x : base )
                {
                    if( x.getProjectFacet() == this.facet )
                    {
                        fromVersion = x;
                        break;
                    }
                }
                
                if( fromVersion != null )
                {
                    for( IActionDefinition def : definitions )
                    {
                        final IVersionExpr vexpr 
                            = (IVersionExpr) def.getProperty( IActionDefinition.PROP_FROM_VERSIONS );
                        
                        if( vexpr == null || vexpr.check( fromVersion ) )
                        {
                            return def;
                        }
                    }
                }
            }
            else
            {
                return definitions.iterator().next();
            }
        }

        return null;
    }
    
    /**
     * @deprecated
     */
    
    @SuppressWarnings( "unchecked" )
    public IActionDefinition getActionDefinition( final Action.Type type )
    
        throws CoreException
        
    {
        final Set definitions = getActionDefinitions( type );
        
        if( definitions.size() == 0 )
        {
            return null;
        }
        else
        {
            return (IActionDefinition) definitions.iterator().next();
        }
    }
    
    /**
     * @deprecated
     */
    
    public Object createActionConfig( final Action.Type type,
                                      final String pjname )
    
        throws CoreException
        
    {
        if( ! supports( type ) )
        {
            final String msg 
                = NLS.bind( Resources.actionNotSupported, toString(), 
                            type.toString() );
            
            throw new CoreException( FacetCorePlugin.createErrorStatus( msg ) );
        }
        
        final IActionDefinition def = getActionDefinition( type );
        
        if( def == null )
        {
            return null;
        }
        else
        {
            return def.createConfigObject( this, pjname );
        }
    }
    
    /**
     * @deprecated
     */
    
    public boolean isSameActionConfig( final Action.Type type,
                                       final IProjectFacetVersion fv )
    
        throws CoreException
        
    {
        return ( (ProjectFacetVersion) fv ).getActionDefinition( type ) == getActionDefinition( type );
    }
    
    public boolean isValidFor( final Set<IProjectFacet> fixed )
    {
        for( IProjectFacet f : fixed )
        {
            if( this.facet == f )
            {
                return true;
            }
        }
        
        for( IProjectFacet f : fixed )
        {
            if( f.getVersions().size() > 0 )
            {
                boolean conflictsWithAllVersions = true;
    
                for( IProjectFacetVersion fv : f.getVersions() )
                {
                    if( ! conflictsWith( fv ) )
                    {
                        conflictsWithAllVersions = false;
                        break;
                    }
                }
                
                if( conflictsWithAllVersions )
                {
                    return false;
                }
            }
        }
        
        return true;
    }
    
    public boolean conflictsWith( final IProjectFacetVersion fv )
    {
        if( this == fv )
        {
            return false;
        }
        else if( this.facet == fv.getProjectFacet() )
        {
            return true;
        }
        else
        {
            return conflictsWith( fv, getConstraint() ) || 
                   conflictsWith( this, fv.getConstraint() );
        }
    }
    
    private boolean conflictsWith( final IProjectFacetVersion fv,
                                   final IConstraint op )
    {
        if( op.getType() == IConstraint.Type.AND )
        {
            for( Object operand : op.getOperands() )
            {
                if( conflictsWith( fv, (IConstraint) operand ) )
                {
                    return true;
                }
            }
            
            return false;
        }
        else if( op.getType() == IConstraint.Type.OR )
        {
            boolean allBranchesConflict = true;
            
            for( Object operand : op.getOperands() )
            {
                if( ! conflictsWith( fv, (IConstraint) operand ) )
                {
                    allBranchesConflict = false;
                    break;
                }
            }
            
            return allBranchesConflict;
        }
        else if( op.getType() == IConstraint.Type.CONFLICTS )
        {
            final Object firstOperand = op.getOperand( 0 );
            
            if( firstOperand instanceof IGroup )
            {
                final IGroup group = (IGroup) firstOperand;
                return group.getMembers().contains( fv );
            }
            else
            {
                final IProjectFacet f = (IProjectFacet) firstOperand;
                final IVersionExpr vexpr = (IVersionExpr) op.getOperand( 1 );
                
                if( fv.getProjectFacet() == f )
                {
                    if( vexpr.check( fv ) )
                    {
                        return true;
                    }
                }
                
                return false;
            }
        }
        else if( op.getType() == IConstraint.Type.REQUIRES )
        {
            final Boolean soft
                = (Boolean) op.getOperand( op.getOperands().size() - 1 );
        
            if( soft.equals( Boolean.TRUE ) )
            {
                return false;
            }
            else
            {
                final Object firstOperand = op.getOperand( 0 );
                boolean conflictsWithAll = true;
                
                if( firstOperand instanceof IGroup )
                {
                    final IGroup group = (IGroup) firstOperand;
                    
                    for( IProjectFacetVersion member : group.getMembers() )
                    {
                        if( ! member.conflictsWith( fv ) )
                        {
                            conflictsWithAll = false;
                            break;
                        }
                    }
                }
                else
                {
                    final IProjectFacet rf = (IProjectFacet) firstOperand;
                    final IVersionExpr vexpr = (IVersionExpr) op.getOperand( 1 );
                    
                    try
                    {
                        final String vexprstr = vexpr.toString();
                        
                        for( IProjectFacetVersion rfv : rf.getVersions( vexprstr ) )
                        {
                            if( ! rfv.conflictsWith( fv ) )
                            {
                                conflictsWithAll = false;
                                break;
                            }
                        }
                    }
                    catch( CoreException e )
                    {
                        FacetCorePlugin.log( e );
                        return false;
                    }
                }
                
                return conflictsWithAll;
            }
        }
        else
        {
            throw new IllegalStateException();
        }
    }
    
    public int compareTo( final Object obj )
    {
        if( obj == this )
        {
            return 0;
        }
        
        if( obj instanceof IProjectFacetVersion )
        {
            final IProjectFacetVersion fv = (IProjectFacetVersion) obj;
            
            if( fv.getProjectFacet() != this.facet )
            {
                final String msg
                    = Resources.bind( Resources.cannotCompareVersionsOfDifferentFacets,
                                      this.facet.getId(), this.version,
                                      fv.getProjectFacet().getId(), 
                                      fv.getVersionString() );
                
                throw new RuntimeException( msg );
            }
            
            final Integer cachedResult = this.compTable.get( fv );
            
            if( cachedResult != null )
            {
                return cachedResult.intValue();
            }
        }

        try
        {
            final Comparator<String> comp = this.facet.getVersionComparator();
            return comp.compare( this.version, ( (IVersion) obj ).getVersionString() );
        }
        catch( Exception e )
        {
            FacetCorePlugin.log( e );
            return 0;
        }
    }
    
    public Map<String,Object> getProperties()
    {
        return this.propertiesReadOnly;
    }
    
    public Object getProperty( final String name )
    {
        return this.properties.get( name );
    }

    void setProperty( final String name,
                      final Object value )
    {
        this.properties.put( name, value );
    }
    
    public String toString()
    {
        if( this.facet.isVersionHidden() )
        {
            return this.facet.getLabel();
        }
        else
        {
            return this.facet.getLabel() + " " + this.version; //$NON-NLS-1$
        }
    }
    
    private static final class Resources
    
        extends NLS
        
    {
        public static String actionNotSupported;
        public static String multipleActionDefinitions;
        public static String cannotCompareVersionsOfDifferentFacets;
        
        static
        {
            initializeMessages( ProjectFacetVersion.class.getName(), 
                                Resources.class );
        }
        
        public static String bind( final String template,
                                   final Object arg1,
                                   final Object arg2,
                                   final Object arg3 )
        {
            return NLS.bind( template, new Object[] { arg1, arg2, arg3 } );
        }

        public static String bind( final String template,
                                   final Object arg1,
                                   final Object arg2,
                                   final Object arg3,
                                   final Object arg4 )
        {
            return NLS.bind( template, new Object[] { arg1, arg2, arg3, arg4 } );
        }
    }

}
