/******************************************************************************
 * 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.IFile;
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.core.runtime.Path;
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.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
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;
    private 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;
        }
        
        final List currentEntries = computeClasspathEntries();
        return ! this.entries.equals( currentEntries );
    }
    
    public abstract void refresh();
    
    static ClasspathDecorationsManager getDecorationsManager()
    {
        return decorations;
    }
    
    private List computeClasspathEntries()
    {
        final List entries = new ArrayList();
        
        final IVirtualComponent vc 
            = ComponentCore.createComponent( this.project );
        
        if( vc == null )
        {
            return entries;
        }
        
        final Set existingEntries 
            = ClasspathUtil.getResolvedClasspath( this.owner, getPath() );
        
        IVirtualReference[] refs = vc.getReferences();
        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()) {
                VirtualArchiveComponent archiveComp = (VirtualArchiveComponent) comp;
                java.io.File diskFile = archiveComp.getUnderlyingDiskFile();
                if (diskFile.exists()) {
                	newPath =new Path(diskFile.getAbsolutePath());
                } else {
                    IFile iFile = archiveComp.getUnderlyingWorkbenchFile();
                    if (!entries.contains(iFile.getFullPath())){
                        newPath = iFile.getFullPath();
                    }
                }
            } else {
                IProject project = comp.getProject();
                newPath = project.getFullPath();    
            }
            
        	if( newPath != null && ! existingEntries.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.getFullPath();
                    
                    if(!jarsHandled.contains(p.lastSegment()) &&  isJarFile( r ) )
                    {
                        jarsHandled.add(p.lastSegment());
                        
                        if( ! existingEntries.contains( p ) )
                        {
                        	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());
                        
                        if( ! existingEntries.contains( p ) )
                        {
                        	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;
                            }
                            else
                            {
                                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 ];
        }
    }
    
}