/******************************************************************************
 * Copyright (c) 2005-2007 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
 ******************************************************************************/

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

import static org.eclipse.wst.common.project.facet.core.internal.FacetCorePlugin.PLUGIN_ID;
import static org.eclipse.wst.common.project.facet.core.internal.FacetCorePlugin.createErrorStatus;
import static org.eclipse.wst.common.project.facet.core.internal.FacetCorePlugin.log;
import static org.eclipse.wst.common.project.facet.core.internal.FacetCorePlugin.logError;
import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findExtensions;
import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findOptionalElement;
import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findRequiredAttribute;
import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.findRequiredElement;
import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.getElementValue;
import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.getTopLevelElements;
import static org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.instantiate;

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

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.project.facet.core.IDynamicPreset;
import org.eclipse.wst.common.project.facet.core.IPreset;
import org.eclipse.wst.common.project.facet.core.IPresetFactory;
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.PresetDefinition;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.util.internal.IndexedSet;
import org.eclipse.wst.common.project.facet.core.util.internal.PluginUtil.InvalidExtensionException;

/**
 * Contains the logic for processing the <code>presets</code> extension point.
 * 
 * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
 */

public final class PresetsExtensionPoint
{
    public static final String EXTENSION_POINT_ID = "presets"; //$NON-NLS-1$
    private static final String OLD_EXTENSION_POINT_ID = "facets"; //$NON-NLS-1$
    
    private static final String EL_DESCRIPTION = "description"; //$NON-NLS-1$
    private static final String EL_DYNAMIC_PRESET = "dynamic-preset"; //$NON-NLS-1$
    private static final String EL_FACET = "facet"; //$NON-NLS-1$
    private static final String EL_FACTORY = "factory"; //$NON-NLS-1$
    private static final String EL_LABEL = "label"; //$NON-NLS-1$
    private static final String EL_PRESET = "preset"; //$NON-NLS-1$
    private static final String EL_STATIC_PRESET = "static-preset"; //$NON-NLS-1$
    private static final String ATTR_CLASS = "class"; //$NON-NLS-1$
    private static final String ATTR_EXTENDS = "extends"; //$NON-NLS-1$
    private static final String ATTR_ID = "id"; //$NON-NLS-1$
    private static final String ATTR_VERSION = "version"; //$NON-NLS-1$
    
    private static final String DEFAULT_DESCRIPTION = ""; //$NON-NLS-1$
    
    private static IndexedSet<String,IPreset> presets = null;
    
    public static Set<IPreset> getPresets()
    {
        readExtensions();
        return presets.getUnmodifiable();
    }
    
    public static IPreset getPreset( final String id )
    {
        readExtensions();
        return presets.get( id );
    }
    
    private static synchronized void readExtensions()
    {
        if( presets != null )
        {
            return;
        }
        
        presets = new IndexedSet<String,IPreset>();        
        
        for( IConfigurationElement element 
             : getTopLevelElements( findExtensions( PLUGIN_ID, EXTENSION_POINT_ID ) ) )
        {
            final String elName = element.getName();
            
            if( elName.equals( EL_STATIC_PRESET ) )
            {
                try
                {
                    readStaticPreset( element );
                }
                catch( InvalidExtensionException e )
                {
                    // Continue. The problem has been reported to the user via the log.
                }
            }
            else if( elName.equals( EL_DYNAMIC_PRESET ) )
            {
                try
                {
                    readDynamicPreset( element );
                }
                catch( InvalidExtensionException e )
                {
                    // Continue. The problem has been reported to the user via the log.
                }
            }
        }

        for( IConfigurationElement element 
             : getTopLevelElements( findExtensions( PLUGIN_ID, OLD_EXTENSION_POINT_ID ) ) )
        {
            if( element.getName().equals( EL_PRESET ) )
            {
                try
                {
                    readStaticPreset( element );
                }
                catch( InvalidExtensionException e )
                {
                    // Continue. The problem has been reported to the user via the log.
                }
            }
        }
        
        // Resolve the base presets. Make sure that no presets are extending presets that do not
        // exist, check for circular references, etc.
        
        Set<IPreset> copy = new HashSet<IPreset>( presets ); 
        
        for( IPreset preset : copy )
        {
            if( presets.contains( preset ) )
            {
                resolveBasePreset( preset, new HashSet<IPreset>() );
            }
        }
        
        // Find static presets that are extending dynamic presets and make them into dynamic
        // presets (StaticExtendingDynamicPreset class).
        
        boolean doAnotherPass = true;
        
        while( doAnotherPass )
        {
            doAnotherPass = false;
            
            for( IPreset preset : presets )
            {
                if( preset.getType() == IPreset.Type.STATIC )
                {
                    final StaticPreset stPreset = (StaticPreset) preset;
                    final String basePresetId = stPreset.getBasePresetId();
                    
                    if( basePresetId != null )
                    {
                        final IPreset basePreset = getPreset( basePresetId );
                        
                        if( basePreset.getType() == IPreset.Type.DYNAMIC )
                        {
                            final StaticExtendingDynamicPreset stPresetNew
                                = new StaticExtendingDynamicPreset( stPreset.getId(), 
                                                                    stPreset.getPluginId(),
                                                                    stPreset.getLabel(),
                                                                    stPreset.getDescription(),
                                                                    stPreset.getBasePresetId(),
                                                                    stPreset.getProjectFacets() );
                            
                            presets.add( stPresetNew.getId(), stPresetNew );

                            doAnotherPass = true;
                            break;
                        }
                    }
                }
            }
        }
    }
    
    private static void readStaticPreset( final IConfigurationElement el )
    
        throws InvalidExtensionException
        
    {
        final String pluginId = el.getContributor().getName();
        final String id = findRequiredAttribute( el, ATTR_ID );
        
        final IConfigurationElement elLabel = findOptionalElement( el, EL_LABEL );
        final String label = getElementValue( elLabel, id );
        
        final IConfigurationElement elDesc = findOptionalElement( el, EL_DESCRIPTION );
        final String description = getElementValue( elDesc, DEFAULT_DESCRIPTION );
        
        String basePreset = el.getAttribute( ATTR_EXTENDS );
        
        if( basePreset != null )
        {
            basePreset = basePreset.trim();
            
            if( basePreset.length() == 0 )
            {
                basePreset = null;
            }
        }
        
        final Set<IProjectFacetVersion> facets = new HashSet<IProjectFacetVersion>();

        for( IConfigurationElement child : el.getChildren() )
        {
            final String childName = child.getName();
            
            if( childName.equals( EL_FACET ) )
            {
                final String fid = findRequiredAttribute( child, ATTR_ID );
                final String fver = findRequiredAttribute( child, ATTR_VERSION );
                
                if( ! ProjectFacetsManager.isProjectFacetDefined( fid ) )
                {
                    final String msg
                        = Resources.bind( Resources.presetUsesUnknownFacet, id, pluginId, fid );
                    
                    logError( msg );
                    
                    return;
                }
                
                final IProjectFacet f = ProjectFacetsManager.getProjectFacet( fid );
                
                if( ! f.hasVersion( fver ) )
                {
                    final String msg
                        = Resources.bind( Resources.presetUsesUnknownFacetVersion, id, pluginId,
                                          fid, fver );
                    
                    logError( msg );
                    
                    return;
                }
                
                final IProjectFacetVersion fv = f.getVersion( fver );
                
                facets.add( fv );
            }
        }
        
        final StaticPreset preset 
            = new StaticPreset( id, pluginId, label, description, basePreset, facets );
        
        presets.add( id, preset );
    }

    private static void readDynamicPreset( final IConfigurationElement el )
    
        throws InvalidExtensionException
        
    {
        final String pluginId = el.getContributor().getName();
        final String id = findRequiredAttribute( el, ATTR_ID );
        final IConfigurationElement elFactory = findRequiredElement( el, EL_FACTORY );
        final String factoryClassName = findRequiredAttribute( elFactory, ATTR_CLASS );
        
        final DynamicPreset preset = new DynamicPreset( id, pluginId, factoryClassName );
        presets.add( id, preset );
    }
    
    private static boolean resolveBasePreset( final IPreset preset,
                                              final Set<IPreset> visitedPresets )
    {
        if( preset.getType() == IPreset.Type.STATIC )
        {
            final StaticPreset stPreset = (StaticPreset) preset;
            final String basePresetId = stPreset.getBasePresetId();
            
            if( basePresetId != null )
            {
                final IPreset basePreset = getPreset( basePresetId );
                boolean problem = false;
                
                visitedPresets.add( preset );
                
                if( basePreset == null )
                {
                    final String msg
                        = Resources.bind( Resources.basePresetNotFound, stPreset.getId(), 
                                          stPreset.getPluginId(), basePresetId );
                    
                    logError( msg );
                    
                    problem = true;
                }
                else if( visitedPresets.contains( basePreset ) )
                {
                    final StringBuilder cycle = new StringBuilder();
                    final int cycleSize = visitedPresets.size();
                    int count = 0;
                    
                    for( IPreset vp : visitedPresets )
                    {
                        count++;
                        
                        if( count > 1 )
                        {
                            if( count == cycleSize )
                            {
                                cycle.append( " and " ); //$NON-NLS-1$
                            }
                            else
                            {
                                cycle.append( ", " ); //$NON-NLS-1$
                            }
                        }
                        
                        cycle.append( '"' );
                        cycle.append( vp.getId() );
                        cycle.append( '"' );
                    }
                    
                    final String msg = Resources.bind( Resources.cycleDetected, cycle.toString() );
                    
                    logError( msg );
                    
                    problem = true;
                }
                else if( ! resolveBasePreset( basePreset, visitedPresets ) )
                {
                    problem = true;
                }

                if( problem )
                {
                    PresetsExtensionPoint.presets.delete( preset.getId() );
                    return false;
                }
            }
        }
        
        return true;
    }
    
    private static class StaticPreset
    
        implements IPreset
        
    {
        private final String id;
        private final String pluginId;
        private final String label;
        private final String description;
        private final String basePresetId;
        private final Set<IProjectFacet> facets;
        private final Set<IProjectFacetVersion> facetVersions;
        private final Set<IProjectFacetVersion> facetVersionsReadOnly;
        
        public StaticPreset( final String id,
                             final String pluginId,
                             final String label,
                             final String description,
                             final String basePreset,
                             final Set<IProjectFacetVersion> facets )
        {
            this.id = id;
            this.pluginId = pluginId;
            this.label = label;
            this.description = description;
            this.basePresetId = basePreset;
            this.facetVersions = facets;
            this.facetVersionsReadOnly = Collections.unmodifiableSet( this.facetVersions );
            
            this.facets = new HashSet<IProjectFacet>( this.facetVersions.size() );
            
            for( IProjectFacetVersion fv : this.facetVersions )
            {
                this.facets.add( fv.getProjectFacet() );
            }
        }
        
        public final String getId()
        {
            return this.id;
        }
        
        public final String getPluginId()
        {
            return this.pluginId;
        }

        public Type getType()
        {
            return Type.STATIC;
        }
        
        public final String getLabel()
        {
            return this.label;
        }

        public final String getDescription()
        {
            return this.description;
        }
        
        public final String getBasePresetId()
        {
            return this.basePresetId;
        }

        public Set<IProjectFacetVersion> getProjectFacets()
        {
            if( this.basePresetId == null )
            {
                return this.facetVersionsReadOnly;
            }
            else
            {
                final IPreset basePreset = getPreset( this.basePresetId );
                return createCombinedFacetSet( basePreset );
            }
        }

        public final boolean isUserDefined()
        {
            return false;
        }
        
        public final String toString()
        {
            return this.id;
        }
        
        public boolean equals( final Object obj )
        {
            if( ! ( obj instanceof StaticPreset ) )
            {
                return false;
            }
            
            final StaticPreset p = (StaticPreset) obj;
            
            return this.id.equals( p.id ) &&
                   this.pluginId.equals( p.pluginId ) &&
                   this.label.equals( p.label ) &&
                   this.description.equals( p.description ) &&
                   this.facetVersions.equals( p.facetVersions );
        }
        
        protected final Set<IProjectFacetVersion> createCombinedFacetSet( final IPreset basePreset )
        {
            final Set<IProjectFacetVersion> result 
                = new HashSet<IProjectFacetVersion>( this.facetVersions );
            
            for( IProjectFacetVersion fv : basePreset.getProjectFacets() )
            {
                if( ! this.facets.contains( fv.getProjectFacet() ) )
                {
                    result.add( fv );
                }
            }
            
            return Collections.unmodifiableSet( result );
        }
    }
    
    private static final class StaticExtendingDynamicPreset
    
        extends StaticPreset
        implements IDynamicPreset
        
    {
        public StaticExtendingDynamicPreset( final String id,
                                             final String pluginId,
                                             final String label,
                                             final String description,
                                             final String basePresetId,
                                             final Set<IProjectFacetVersion> facets )
        {
            super( id, pluginId, label, description, basePresetId, facets );
        }
        
        @Override
        public Type getType()
        {
            return Type.DYNAMIC;
        }
        
        @Override
        public Set<IProjectFacetVersion> getProjectFacets()
        {
            return Collections.emptySet();
        }

        public IPreset resolve( final Map<String,Object> context )
        {
            final IDynamicPreset basePreset = (IDynamicPreset) getPreset( getBasePresetId() );
            final IPreset resBasePreset = basePreset.resolve( context );
            
            if( resBasePreset == null )
            {
                return null;
            }
            else
            {
                final Set<IProjectFacetVersion> facets = createCombinedFacetSet( resBasePreset );
                
                return new StaticPreset( getId(), getPluginId(), getLabel(), getDescription(), 
                                         getBasePresetId(), facets );
            }
        }
    }
    
    private static final class DynamicPreset
    
        implements IDynamicPreset
        
    {
        private final String id;
        private final String pluginId;
        private final String factoryClassName;
        
        public DynamicPreset( final String id,
                              final String pluginId,
                              final String factoryClassName )
        {
            this.id = id;
            this.pluginId = pluginId;
            this.factoryClassName = factoryClassName;
        }

        public String getId()
        {
            return this.id;
        }
        
        public Type getType()
        {
            return Type.DYNAMIC;
        }

        public String getLabel()
        {
            return this.id;
        }

        public String getDescription()
        {
            return ""; //$NON-NLS-1$
        }

        public Set<IProjectFacetVersion> getProjectFacets()
        {
            return Collections.emptySet();
        }

        public boolean isUserDefined()
        {
            return false;
        }
        
        public IPreset resolve( final Map<String,Object> context )
        {
            IPresetFactory factory = null;
            
            try
            {
                factory = instantiate( this.pluginId, this.factoryClassName, IPresetFactory.class );
            }
            catch( CoreException e )
            {
                log( e.getStatus() );
            }
            
            if( factory != null )
            {
                PresetDefinition def = null;
                
                try
                {
                    def = factory.createPreset( this.id, context );
                }
                catch( Exception e )
                {
                    final String msg 
                        = Resources.bind( Resources.failedWhileInvokingPresetFactory, 
                                          this.pluginId );
                    
                    log( createErrorStatus( msg, e ) );
                }
                
                if( def != null )
                {
                    final StaticPreset staticPreset
                        = new StaticPreset( this.id, this.pluginId, def.getLabel(), 
                                            def.getDescription(), null, def.getProjectFacets() );
                    
                    return staticPreset;
                }
            }
            
            return null;
        }
        
        public String toString()
        {
            return this.id;
        }
    }
    
    private static final class Resources
    
        extends NLS
        
    {
        public static String presetUsesUnknownFacet;
        public static String presetUsesUnknownFacetVersion;
        public static String basePresetNotFound;
        public static String cycleDetected;
        public static String failedWhileInvokingPresetFactory;
        
        static
        {
            initializeMessages( PresetsExtensionPoint.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 } );
        }
    }
    
}
