/******************************************************************************
 * Copyright (c) 2005 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 API and implementation
 ******************************************************************************/

package org.eclipse.jst.common.project.facet.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.IProjectFacetVersion;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.eclipse.wst.common.project.facet.core.runtime.IRuntime;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

/**
 * <p>A utility used in conjunction with IClasspathProvider in order to manage
 * the bookkeeping when project facets are installed and uninstalled, and when
 * the bound runtime changes. This utility tracks which classpath entries were
 * added to the project by which facet and stores this information in a project
 * metadata file. This enables the classpath entries to be removed without
 * knowing what they are. It is only necessary to know which facet added them.
 * This utility supports the case where the same classpath entry is added by
 * multiple project facets. In this situation, a classpath entry is only
 * removed when the removal has been requested for all of the facets that added
 * it.</p>
 * 
 * <p>Typically the project facet author will write something like this in the
 * install delegate:</p>
 * 
 * <pre>
 * if( ! ClasspathHelper.addClasspathEntries( project, fv )
 * {
 *     // Handle the case when there is no bound runtime or when the bound
 *     // runtime cannot provide classpath entries for this facet.
 *     
 *     final List alternate = ...;
 *     ClasspathHelper.addClasspathEntries( project, fv, alternate );
 * }
 * </pre>
 * 
 * <p>And something like this in the uninstall delegate:</p>
 * 
 * <pre>
 * ClasspathHelper.removeClasspathEntries( project, fv );
 * </pre>
 * 
 * <p>And something like this in the runtime changed delegate:</p>
 * 
 * <pre>
 * ClasspathHelper.removeClasspathEntries( project, fv );
 * 
 * if( ! ClasspathHelper.addClasspathEntries( project, fv )
 * {
 *     // Handle the case when there is no bound runtime or when the bound
 *     // runtime cannot provide classpath entries for this facet.
 *     
 *     final List alternate = ...;
 *     ClasspathHelper.addClasspathEntries( project, fv, alternate );
 * }
 * </pre>
 * 
 * <p>And something like this in the version change delegate:</p>
 * 
 * <pre>
 * final IProjectFacetVersion oldver
 *   = fproj.getInstalledVersion( fv.getProjectFacet() );
 * 
 * ClasspathHelper.removeClasspathEntries( project, oldver );
 * 
 * if( ! ClasspathHelper.addClasspathEntries( project, fv )
 * {
 *     // Handle the case when there is no bound runtime or when the bound
 *     // runtime cannot provide classpath entries for this facet.
 *     
 *     final List alternate = ...;
 *     ClasspathHelper.addClasspathEntries( project, fv, alternate );
 * }
 * </pre>
 * 
 * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
 */

public final class ClasspathHelper
{
    private static final String PLUGIN_ID
        = "org.eclipse.jst.common.project.facet.core";
    
    private static final Object SYSTEM_OWNER = new Object();
    
    private ClasspathHelper() {}
    
    /**
     * Convenience method for adding to the project the classpath entries
     * provided for the specified project facet by the runtime bound to the
     * project. The entries are marked as belonging to the specified project
     * facet.
     *   
     * @param project the project
     * @param fv the project facet version that will own these entries
     * @return <code>true</code> if classpath entries were added, or
     *   <code>false</code> if there is no runtime bound to the project or if
     *   it cannot provide classpath entries for the specified facet
     * @throws CoreException if failed while adding the classpath entries
     */
    
    public static boolean addClasspathEntries( final IProject project,
                                               final IProjectFacetVersion fv )
    
        throws CoreException
        
    {
        final IFacetedProject fproj 
            = ProjectFacetsManager.create( project );
    
        final IRuntime runtime = fproj.getPrimaryRuntime();
        
        if( runtime != null )
        {
            final IClasspathProvider cpprov 
                = (IClasspathProvider) runtime.getAdapter( IClasspathProvider.class );
            
            final List cpentries = cpprov.getClasspathEntries( fv );
            
            if( cpentries != null )
            {
                addClasspathEntries( project, fv, cpentries );
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Add the provided classpath entries to project and marks them as belonging
     * to the specified project facet.
     * 
     * @param project the project
     * @param fv the project facet version that will own these entries
     * @param cpentries the classpath entries (element type: 
     *   {@see IClasspathEntry})
     * @throws CoreException if failed while adding the classpath entries
     */
    
    public static void addClasspathEntries( final IProject project,
                                            final IProjectFacetVersion fv,
                                            final List cpentries )
    
        throws CoreException
        
    {
        try
        {
            final IJavaProject jproj = JavaCore.create( project );
            final List cp = getClasspath( jproj );
            boolean cpchanged = false;

            final Map prefs = readPreferences( project );
            
            for( Iterator itr = cpentries.iterator(); itr.hasNext(); )
            {
                final IClasspathEntry cpentry = (IClasspathEntry) itr.next();
                final IPath path = cpentry.getPath();
                
                final boolean contains = cp.contains( cpentry );
                
                Set owners = (Set) prefs.get( path );
                
                if( owners == null )
                {
                    owners = new HashSet();

                    if( contains )
                    {
                        owners.add( SYSTEM_OWNER );
                    }
                    
                    prefs.put( path, owners );
                }
                
                owners.add( fv );
                
                if( ! contains )
                {
                    cp.add( cpentry );
                    cpchanged = true;
                }
            }
            
            if( cpchanged )
            {
                setClasspath( jproj, cp );
            }
            
            writePreferences( project, prefs );
        }
        catch( BackingStoreException e )
        {
            final IStatus st
                = new Status( IStatus.ERROR, PLUGIN_ID, 0, 
                              Resources.failedWritingPreferences, e );
            
            throw new CoreException( st );
        }
    }
    
    /**
     * Removes the classpath entries belonging to the specified project facet.
     * Any entries that also belong to another facet are left in place.
     * 
     * @param project the project
     * @param fv the project facet that owns the entries that should be removed
     * @throws CoreException if failed while removing classpath entries
     */
    
    public static void removeClasspathEntries( final IProject project,
                                               final IProjectFacetVersion fv )
    
        throws CoreException
        
    {
        try
        {
            final IJavaProject jproj = JavaCore.create( project );
            final List cp = getClasspath( jproj );
            boolean cpchanged = false;

            final Map prefs = readPreferences( project );
            
            for( Iterator itr1 = prefs.entrySet().iterator(); itr1.hasNext(); )
            {
                final Map.Entry entry = (Map.Entry) itr1.next();
                final IPath path = (IPath) entry.getKey();
                final Set owners = (Set) entry.getValue();
                
                if( owners.contains( fv ) )
                {
                    owners.remove( fv );
                    
                    if( owners.size() == 0 )
                    {
                        itr1.remove();
                        
                        for( Iterator itr2 = cp.iterator(); itr2.hasNext(); )
                        {
                            final IClasspathEntry cpentry
                                = (IClasspathEntry) itr2.next();
                            
                            if( cpentry.getPath().equals( path ) )
                            {
                                itr2.remove();
                                cpchanged = true;
                                break;
                            }
                        }
                    }
                }
            }

            if( cpchanged )
            {
                setClasspath( jproj, cp );
            }
            
            writePreferences( project, prefs );
        }
        catch( BackingStoreException e )
        {
            final IStatus st
                = new Status( IStatus.ERROR, PLUGIN_ID, 0, 
                              Resources.failedWritingPreferences, e );
            
            throw new CoreException( st );
        }
    }
    
    private static List getClasspath( final IJavaProject jproj )
    
        throws CoreException
        
    {
        final ArrayList list = new ArrayList();
        final IClasspathEntry[] cp = jproj.getRawClasspath();
        
        for( int i = 0; i < cp.length; i++ )
        {
            list.add( cp[ i ] );
        }
        
        return list;
    }
    
    private static void setClasspath( final IJavaProject jproj,
                                      final List cp )
    
        throws CoreException
        
    {
        final IClasspathEntry[] newcp
            = (IClasspathEntry[]) cp.toArray( new IClasspathEntry[ cp.size() ] );
        
        jproj.setRawClasspath( newcp, null );
    }
    
    private static Map readPreferences( final IProject project )
    
        throws BackingStoreException
        
    {
        final Preferences root = getPreferencesNode( project );
        final Map result = new HashMap();
        
        final String[] keys = root.childrenNames();
        
        for( int i = 0; i < keys.length; i++ )
        {
            final String key = keys[ i ];
            final Preferences node = root.node( key );
            
            final String owners = node.get( "owners", null );
            final String[] split = owners.split( ";" );
            final Set set = new HashSet();
            
            for( int j = 0; j < split.length; j++ )
            {
                final String segment = split[ j ];
                
                if( segment.equals( "#system#" ) )
                {
                    set.add( SYSTEM_OWNER );
                }
                else
                {
                    final IProjectFacetVersion fv 
                        = parseFeatureVersion( segment );
                    
                    set.add( fv );
                }
            }
            
            result.put( decode( key ), set );
        }
        
        return result;
    }
    
    private static void writePreferences( final IProject project,
                                          final Map prefs )
    
        throws BackingStoreException
        
    {
        final Preferences root = getPreferencesNode( project );
        final String[] children = root.childrenNames();
        
        for( int i = 0; i < children.length; i++ )
        {
            root.node( children[ i ] ).removeNode();
        }
        
        for( Iterator itr1 = prefs.entrySet().iterator(); itr1.hasNext(); )
        {
            final Map.Entry entry = (Map.Entry) itr1.next();
            final IPath path = (IPath) entry.getKey();
            final Set owners = (Set) entry.getValue();
            
            final StringBuffer buf = new StringBuffer();
            
            for( Iterator itr2 = owners.iterator(); itr2.hasNext(); )
            {
                final Object owner = itr2.next();

                if( buf.length() > 0 ) 
                {
                    buf.append( ';' );
                }
                
                if( owner == SYSTEM_OWNER )
                {
                    buf.append( "#system#" );
                }
                else
                {
                    final IProjectFacetVersion fv 
                        = (IProjectFacetVersion) owner;
                    
                    buf.append( fv.getProjectFacet().getId() );
                    buf.append( ':' );
                    buf.append( fv.getVersionString() );
                }
            }

            final Preferences node = root.node( encode( path ) );
            node.put( "owners", buf.toString() );
        }
        
        root.flush();
    }
    
    
    private static Preferences getPreferencesNode( final IProject project )
    {
        final ProjectScope scope = new ProjectScope( project );
        final IEclipsePreferences pluginRoot = scope.getNode( PLUGIN_ID );
        return pluginRoot.node( "classpath.helper" );
    }
    
    private static IProjectFacetVersion parseFeatureVersion( final String str )
    {
        final int colon = str.indexOf( ':' );
        final String id = str.substring( 0, colon );
        final String ver = str.substring( colon + 1 );
        
        return ProjectFacetsManager.getProjectFacet( id ).getVersion( ver );
    }
    
    private static String encode( final IPath path )
    {
        return path.toString().replaceAll( "/", "::" );
    }
    
    private static IPath decode( final String path )
    {
        return new Path( path.replaceAll( "::", "/" ) );
    }
    
    private static final class Resources
    
        extends NLS
        
    {
        public static String failedWritingPreferences;
        
        static
        {
            initializeMessages( ClasspathHelper.class.getName(), 
                                Resources.class );
        }
    }

}
