/******************************************************************************
 * Copyright (c) 2005, 2006 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.jdt.internal.classpath;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.common.frameworks.CommonFrameworksPlugin;
import org.eclipse.jst.common.internal.modulecore.IClasspathDependencyComponent;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.internal.util.IModuleConstants;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;

/**
 * @author <a href="mailto:kosta@bea.com">Konstantin Komissarchik</a>
 */

public abstract class FlexibleProjectContainer

    implements IClasspathContainer

{
    protected static final class PathType
    {
        public static final PathType 
            LIB_DIRECTORY = new PathType(),
            CLASSES_DIRECTORY = new PathType();
    }
    
    private static ClasspathDecorationsManager decorations; 

    static
    {
        // Register the resource listener that will listen for changes to
        // resources relevant to flexible project containers across the
        // workspace and refresh them as necessary.
        
        Listener.register();
        
        // Read the decorations from the workspace metadata.
        
        final String plugin = CommonFrameworksPlugin.PLUGIN_ID;
        decorations = new ClasspathDecorationsManager( plugin );
    }

    private static final String SEPARATOR = "!"; //$NON-NLS-1$
    
    public static String getDecorationManagerKey(IProject project, String container){
    	return project.getName() + SEPARATOR + container;
    }
    
    protected final IPath path;
    protected final IJavaProject owner;
    protected final IProject project;
    private final IPath[] paths;
    private final PathType[] pathTypes;
    protected final List entries;
    private final IClasspathEntry[] cpentries;
    private static final Set containerTypes = new HashSet();
    
    public FlexibleProjectContainer( final IPath path,
                                     final IJavaProject owner,
                                     final IProject project,
                                     final IPath[] paths,
                                     final PathType[] types )
    {
        this.path = path;
        this.owner = owner;
        this.project = project;
        this.paths = paths;
        this.pathTypes = types;
        
        if( ! isFlexibleProject( this.project ) )
        {
            // Silently noop if the referenced project is not a flexible
            // project. Should I be doing something else here?
            
            this.entries = Collections.EMPTY_LIST;
            this.cpentries = new IClasspathEntry[ 0 ];
            
            return;
        }
        
        addFlexibleProjectContainerType( path.segment( 0 ) );
        
        this.entries = computeClasspathEntries();
        this.cpentries = new IClasspathEntry[ this.entries.size() ];
        
        for( int i = 0, n = this.entries.size(); i < n; i++ )
        {
            IPath entryPath = (IPath) this.entries.get( i );
            IResource resource =ResourcesPlugin.getWorkspace().getRoot().findMember(entryPath); 
            if(null != resource && resource.getType() == IResource.PROJECT)
                this.cpentries[ i ] = JavaCore.newProjectEntry(entryPath, false);
            else
                this.cpentries[ i ] = newLibraryEntry( entryPath );
        }
    }
    
    public int getKind()
    {
        return K_APPLICATION;
    }

    public IPath getPath()
    {
        return this.path;
    }
    
    public IClasspathEntry[] getClasspathEntries()
    {
        return this.cpentries;
    }
    
    public boolean isOutOfDate( final IResourceDelta delta )
    {
        if( delta == null )
        {
            return false;
        }
        return isOutOfDate();
    }

	public boolean isOutOfDate() {
		final List currentEntries = computeClasspathEntries();
        return ! this.entries.equals( currentEntries );
	}
    
    public abstract void refresh();
    
	/**
	 * If forceUpdate is <code>false</code> then a refresh is made only if
	 * {@link #isOutOfDate()} returns <code>true</code>. If forceUpdate is
	 * <code>true</code> then a refresh is immediately made without checking
	 * {@link #isOutOfDate()}.
	 * 
	 * @param forceUpdate
	 */
    public void refresh(boolean forceUpdate){
    	if(forceUpdate || isOutOfDate()){
    		refresh();
    	}
    }
    
    static ClasspathDecorationsManager getDecorationsManager()
    {
        return decorations;
    }
    
    protected IVirtualReference [] computeReferences(IVirtualComponent vc){
    	return vc.getReferences();
    }
    
    protected List computeClasspathEntries()
    {
        final List entries = new ArrayList();
        
        final IVirtualComponent vc 
            = ComponentCore.createComponent( this.project );
        
        if( vc == null )
        {
            return entries;
        }
        
        IVirtualReference[] refs = computeReferences(vc);
        IVirtualComponent comp = null;
        Set jarsHandled = new HashSet();
        String jarName = null;
        for (int i = 0; i < refs.length; i++) {
            comp = refs[i].getReferencedComponent();
            if (!refs[i].getRuntimePath().equals(paths[0].makeAbsolute()))
                continue;
            jarName = refs[i].getArchiveName();
            if(null != jarName){
                jarsHandled.add(jarName);
            }
            IPath newPath = null;
            if (comp.isBinary()) {
            	if( comp instanceof IClasspathDependencyComponent )
            		continue;
            	newPath = (IPath)comp.getAdapter(IPath.class);
            } else
                newPath = comp.getProject().getFullPath();    
            
        	if( newPath != null && !entries.contains(newPath))
                entries.add( newPath );
        }
        
        for( int i = 0; i < this.paths.length; i++ )
        {
            final IVirtualFolder rootFolder = vc.getRootFolder();
            final IVirtualFolder vf = rootFolder.getFolder( paths[ i ] );
            
            if( this.pathTypes[ i ] == PathType.LIB_DIRECTORY )
            {
                final IVirtualResource[] contents;
                
                try
                {
                    contents = members( vf );
                }
                catch( CoreException e )
                {
                    CommonFrameworksPlugin.log( e );
                    continue;
                }

                for( int j = 0; j < contents.length; j++ )
                {
                    final IResource r = contents[ j ].getUnderlyingResource();
                    final IPath p = r.getLocation();
                    
                    if(!jarsHandled.contains(p.lastSegment()) &&  isJarFile( r ) )
                    {
                        jarsHandled.add(p.lastSegment());                  
                       	entries.add( p );
                    }
                }
            }
            else
            {
                final IContainer[] uf = vf.getUnderlyingFolders();
                
                for( int j = 0; j < uf.length; j++ )
                {
                    final IPath p = uf[ j ].getFullPath();
                    
                    if( ! jarsHandled.contains( p.lastSegment() ) && 
                        ! isSourceOrOutputDirectory( p ) )
                    {
                        jarsHandled.add(p.lastSegment());
                       	entries.add( p );
                    }
                }
            }
        }

        return entries;
    }

    // TODO: This method was created to provide a safe last-minute workaround
    // for the issue described in https://bugs.eclipse.org/bugs/show_bug.cgi?id=162974.
    // This code needs to be revisited in a future release to find a more
    // permanent solution.

    protected IVirtualResource[] members( final IVirtualFolder vf ) 
    
        throws CoreException 
        
    {
        return vf.members();
    }
    
    private IClasspathEntry newLibraryEntry( final IPath p )
    {
        IPath srcpath = null;
        IPath srcrootpath = null;
        IClasspathAttribute[] attrs = {};
        IAccessRule[] access = {};
        
        final ClasspathDecorations dec 
            = decorations.getDecorations( getDecorationManagerKey(project, getPath().toString()), p.toString() );
        
        if( dec != null )
        {
            srcpath = dec.getSourceAttachmentPath();
            srcrootpath = dec.getSourceAttachmentRootPath();
            attrs = dec.getExtraAttributes();
        }
        
        return JavaCore.newLibraryEntry( p, srcpath, srcrootpath, access, attrs,
                                         false );
        
    }
    
    private boolean isSourceOrOutputDirectory( final IPath aPath )
    {
        if( isJavaProject( this.project ) )
        {
            try
            {
                final IJavaProject jproject = JavaCore.create( this.project );
                final IClasspathEntry[] cp = jproject.getRawClasspath();
                
                for( int i = 0; i < cp.length; i++ )
                {
                    final IClasspathEntry cpe = cp[ i ];
                    
                    if( cpe.getEntryKind() == IClasspathEntry.CPE_SOURCE )
                    {
                        final IPath src = cpe.getPath();
                        final IPath output = cpe.getOutputLocation();
                        
                        if( src.equals( aPath ) ||
                            output != null && output.equals( aPath ) )
                        {
                            return true;
                        }
                    }
                }
                
                if( jproject.getOutputLocation().equals( aPath ) )
                {
                    return true;
                }
            }
            catch( JavaModelException e )
            {
                CommonFrameworksPlugin.log( e );
            }
        }
    
        return false;    
    }
    
    private static boolean isJavaProject( final IProject pj )
    {
        try
        {
            return pj.getNature( JavaCore.NATURE_ID ) != null;
        }
        catch( CoreException e )
        {
            return false;
        }
    }

    private static boolean isFlexibleProject( final IProject pj )
    {
        try
        {
            return pj.getNature( IModuleConstants.MODULE_NATURE_ID ) != null;
        }
        catch( CoreException e )
        {
            return false;
        }
    }
    
    private static boolean isJarFile( final IResource f )
    {
        if( f.getType() == IResource.FILE )
        {
            final String fname = f.getName();
            
            if( fname.endsWith( ".jar" ) || fname.endsWith( ".zip" ) ) //$NON-NLS-1$ //$NON-NLS-2$
            {
                return true;
            }
        }
        
        return false;
    }
    
    private static boolean isMetadataFile( final IResource f )
    {
        if( f.getType() == IResource.FILE )
        {
            final String fname = f.getName();

            if( fname.equals( ".component" ) || //$NON-NLS-1$
                fname.equals( "org.eclipse.wst.common.component" ) || //$NON-NLS-1$
                fname.equals( ".classpath")) //$NON-NLS-1$
            {
                return true;
            }
        }
        
        return false;
    }
    
    private static boolean isFlexibleProjectContainer( final IPath path )
    {
        synchronized( containerTypes )
        {
            return containerTypes.contains( path.segment( 0 ) );
        }
    }
    
    private static void addFlexibleProjectContainerType( final String type )
    {
        synchronized( containerTypes )
        {
            containerTypes.add( type );
        }
    }
    
    private static final class Listener
    
        implements IResourceChangeListener
        
    {
        public static void register()
        {
            final Listener listener = new Listener();
            final IWorkspace ws = ResourcesPlugin.getWorkspace();
            ws.addResourceChangeListener( listener, IResourceChangeEvent.PRE_BUILD );
        }
        
        public void resourceChanged( final IResourceChangeEvent event )
        {
            // Screen the delta before going any further. 
            
            if( ! isInterestingEvent( event ) )
            {
                return;
            }
            
            // Locate all of the flexible project containers.
            
            final ArrayList containers = new ArrayList();
            
            final IProject[] projects 
                = ResourcesPlugin.getWorkspace().getRoot().getProjects();
            
            for( int i = 0; i < projects.length; i++ )
            {
                final IProject project = projects[ i ];
                
                try
                {
                    if( isJavaProject( project ) )
                    {
                        final IJavaProject jproj = JavaCore.create( project );
                        final IClasspathEntry[] cpes = jproj.getRawClasspath();
                        
                        for( int j = 0; j < cpes.length; j++ )
                        {
                            final IClasspathEntry cpe = cpes[ j ];
                            final IPath path = cpe.getPath();
                            
                            if( cpe.getEntryKind() == IClasspathEntry.CPE_CONTAINER &&
                                isFlexibleProjectContainer( path ) )
                            {
                                final IClasspathContainer cont
                                    = JavaCore.getClasspathContainer( path, jproj );
                                
                                containers.add( cont );
                            }
                        }
                    }
                }
                catch( JavaModelException e )
                {
                    CommonFrameworksPlugin.log( e );
                }
            }
            
            // Refresh the containers that are out of date.
            
            final IResourceDelta delta = event.getDelta();
            
            for( int i = 0, n = containers.size(); i < n; i++ )
            {
                final FlexibleProjectContainer c 
                    = (FlexibleProjectContainer) containers.get( i );
                
                if( c.isOutOfDate( delta ) )
                {
                    c.refresh();
                }
            }
        }

        private static boolean isInterestingEvent( final IResourceChangeEvent event )
        {
            final boolean[] result = new boolean[ 1 ];
            
            final IResourceDeltaVisitor visitor = new IResourceDeltaVisitor()
            {
                public boolean visit( final IResourceDelta delta ) 
                {
                    final IResource r = delta.getResource();
                    
                    switch( r.getType() )
                    {
                        case IResource.ROOT:
                        {
                            return true;
                        }
                        case IResource.PROJECT:
                        {
                            return ModuleCoreNature.isFlexibleProject( (IProject) r );
                        }
                        case IResource.FOLDER:
                        {
                            final int kind = delta.getKind();
                            
                            if( kind == IResourceDelta.ADDED ||
                                kind == IResourceDelta.REMOVED )
                            {
                                result[ 0 ] = true;
                                return false;
                            }
                            return true;
                        }
                        case IResource.FILE:
                        {
                            if( isJarFile( r ) || isMetadataFile( r ) )
                            {
                                result[ 0 ] = true;
                            }
                            
                            return false;
                        }
                        default:
                        {
                            return false;
                        }
                    }
                }
            };
            
            try
            {
                event.getDelta().accept( visitor, false );
            }
            catch( CoreException e )
            {
                CommonFrameworksPlugin.log( e );
            }
            
            return result[ 0 ];
        }
    }
    
}