/******************************************************************************
 * Copyright (c) 2010 Oracle
 * 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.jst.common.project.facet.core.internal;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.resources.ResourcesPlugin;
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.preferences.IEclipsePreferences;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.ClasspathEntry;
import org.eclipse.wst.common.project.facet.core.IProjectFacet;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;

/**
 * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
 */

@SuppressWarnings( "restriction" )
public final class ClasspathUtil
{
    public static final String LEGACY_METADATA_FILE_NAME 
        = ".settings/org.eclipse.jst.common.project.facet.core.prefs"; //$NON-NLS-1$

    public static final Object SYSTEM_OWNER = new Object();
    private static final String OWNER_PROJECT_FACETS_ATTR = "owner.project.facets"; //$NON-NLS-1$
    
    private ClasspathUtil() {}

    public static List<IClasspathEntry> getProjectClasspath( final IJavaProject project )
    
        throws CoreException
        
    {
        final List<IClasspathEntry> result = new ArrayList<IClasspathEntry>();
        
        for( IClasspathEntry cpe : project.getRawClasspath() )
        {
            result.add( cpe );
        }
        
        return result;
    }
    
    public static void setProjectClasspath( final IJavaProject project,
                                            final List<IClasspathEntry> cp )
    
        throws CoreException
        
    {
        validateClasspathEdit( project );
        project.setRawClasspath( cp.toArray( new IClasspathEntry[ cp.size() ] ), null );
    }
    
    public static void addClasspathEntry( final IProject project,
                                          final IClasspathEntry cpe )
    
        throws CoreException
        
    {
        addClasspathEntry( JavaCore.create( project ), cpe );
    }

    public static void addClasspathEntry( final IJavaProject project,
                                          final IClasspathEntry cpe )
    
        throws CoreException
        
    {
        validateClasspathEdit( project );
        
        final IClasspathEntry[] cpOld = project.getRawClasspath();
        final IClasspathEntry[] cpNew = new IClasspathEntry[ cpOld.length + 1 ];
        System.arraycopy( cpOld, 0, cpNew, 0, cpOld.length );
        cpNew[ cpOld.length ] = cpe;
        project.setRawClasspath( cpNew, null );
    }

    public static List<IClasspathEntry> getClasspathEntries( final IProject project,
                                                             final IProjectFacet facet )
                                                             
        throws CoreException
        
    {
        final IJavaProject jproj = JavaCore.create( project );
        return getClasspathEntries( jproj, facet );
    }
    
    public static List<IClasspathEntry> getClasspathEntries( final IJavaProject project,
                                                             final IProjectFacet facet )
    
        throws CoreException
        
    {
        final List<IClasspathEntry> result = new ArrayList<IClasspathEntry>();
        
        for( IClasspathEntry cpe : project.getRawClasspath() )
        {
            final Set<Object> owners = getOwners( project, cpe );
            
            if( owners.contains( facet ) )
            {
                result.add( cpe );
            }
        }
        
        return result;
    }
    
    
    public static void addClasspathEntries( final IProject project,
                                            final IProjectFacet facet,
                                            final List<IClasspathEntry> cpentries )
    
        throws CoreException
        
    {
        final IJavaProject jproj = JavaCore.create( project );
        addClasspathEntries( jproj, facet, cpentries );
    }
    
    public static void addClasspathEntries( final IJavaProject project,
                                            final IProjectFacet facet,
                                            final List<IClasspathEntry> cpentries )
    
        throws CoreException
        
    {
        validateClasspathEdit( project );
        convertLegacyMetadata( project );
        
        final List<IClasspathEntry> cp = getProjectClasspath( project );
        
        for( IClasspathEntry cpe : cpentries )
        {
            IClasspathEntry existingClasspathEntry = null;
            
            for( IClasspathEntry x : cp )
            {
                if( x.getPath().equals( cpe.getPath() ) )
                {
                    existingClasspathEntry = x;
                    break;
                }
            }

            final Set<Object> owners = getOwners( project, existingClasspathEntry );
            
            owners.add( facet );
            
            if( existingClasspathEntry != null )
            {
                final IClasspathEntry annotatedEntry = setOwners( existingClasspathEntry, owners );
                final int existingIndex = cp.indexOf( existingClasspathEntry );
                cp.set( existingIndex, annotatedEntry );
            }
            else
            {
                final IClasspathEntry annotatedEntry = setOwners( cpe, owners );
                cp.add( annotatedEntry );
            }
        }

        setProjectClasspath( project, cp );
    }
    
    public static void removeClasspathEntries( final IProject project,
                                               final IProjectFacet facet )
    
        throws CoreException
        
    {
        final IJavaProject jproj = JavaCore.create( project );
        removeClasspathEntries( jproj, facet );
    }
        
    public static void removeClasspathEntries( final IJavaProject project,
                                               final IProjectFacet facet )
    
        throws CoreException
        
    {
        validateClasspathEdit( project );
        convertLegacyMetadata( project );
        
        final List<IClasspathEntry> cp = getProjectClasspath( project );
        boolean cpchanged = false;
        
        for( ListIterator<IClasspathEntry> itr = cp.listIterator(); itr.hasNext(); )
        {
            final IClasspathEntry cpe = itr.next();
            final Set<Object> owners = getOwners( project, cpe );
            
            if( owners.remove( facet ) )
            {
                if( owners.size() == 0 )
                {
                    itr.remove();
                }
                else
                {
                    itr.set( setOwners( cpe, owners ) );
                }
                
                cpchanged = true;
            }
        }

        if( cpchanged )
        {
            setProjectClasspath( project, cp );
        }
    }

    public static void removeClasspathEntries( final IProject project,
                                               final IProjectFacet facet,
                                               final List<IClasspathEntry> cpentries )
    
        throws CoreException
        
    {
        final IJavaProject jproj = JavaCore.create( project );
        removeClasspathEntries( jproj, facet, cpentries );
    }
        
    public static void removeClasspathEntries( final IJavaProject project,
                                               final IProjectFacet facet,
                                               final List<IClasspathEntry> cpentries )
    
        throws CoreException
        
    {
        validateClasspathEdit( project );
        convertLegacyMetadata( project );
        
        final List<IClasspathEntry> cp = getProjectClasspath( project );
        boolean cpchanged = false;
        
        for( ListIterator<IClasspathEntry> itr = cp.listIterator(); itr.hasNext(); )
        {
            final IClasspathEntry cpe = itr.next();
            
            if( cpentries.contains( cpe ) )
            {
                final Set<Object> owners = getOwners( project, cpe );
                
                if( owners.remove( facet ) )
                {
                    if( owners.size() == 0 )
                    {
                        itr.remove();
                    }
                    else
                    {
                        itr.set( setOwners( cpe, owners ) );
                    }
                    
                    cpchanged = true;
                }
            }
        }

        if( cpchanged )
        {
            setProjectClasspath( project, cp );
        }
    }
    
    private static Set<Object> getOwners( final IJavaProject project,
                                          final IClasspathEntry cpe )
                                          
        throws CoreException
        
    {
        final Set<Object> owners = new HashSet<Object>();
        
        if( cpe != null )
        {
            for( IClasspathAttribute attr : cpe.getExtraAttributes() )
            {
                if( attr.getName().equals( OWNER_PROJECT_FACETS_ATTR ) )
                {
                    owners.addAll( decodeOwnersString( attr.getValue() ) );
                    break;
                }
            }
            
            owners.addAll( getOwnersFromLegacyMetadata( project, cpe ) );
            
            if( owners.isEmpty() )
            {
                owners.add( SYSTEM_OWNER );
            }
        }
        
        return owners;
    }

    private static Set<Object> getOwnersFromLegacyMetadata( final IJavaProject project,
                                                            final IClasspathEntry cpe )
    
        throws CoreException
        
    {
        final IProject pj = project.getProject();
        final IFile legacyMetadataFile = pj.getFile( LEGACY_METADATA_FILE_NAME );
        
        if( legacyMetadataFile.exists() )
        {
            final ProjectScope scope = new ProjectScope( pj );
            final IEclipsePreferences pluginRoot = scope.getNode( FacetCorePlugin.PLUGIN_ID );
            final Preferences root = pluginRoot.node( "classpath.helper" ); //$NON-NLS-1$
            
            final String[] keys;
            
            try
            {
                keys = root.childrenNames();
            }
            catch( BackingStoreException e )
            {
                throw new CoreException( FacetCorePlugin.createErrorStatus( e.getMessage(), e ) );
            }
            
            for( String key : keys )
            {
                final Preferences node = root.node( key );
                final String owners = node.get( "owners", null ); //$NON-NLS-1$
                
                if( owners != null )
                {
                    final IPath path = new Path( key.replaceAll( "::", "/" ) ); //$NON-NLS-1$ //$NON-NLS-2$
                    
                    if( cpe.getPath().equals( path ) )
                    {
                        return decodeOwnersString( owners );
                    }
                }
            }
        }
        
        return Collections.emptySet();
    }

    private static IClasspathEntry setOwners( final IClasspathEntry cpe,
                                              final Set<Object> owners )
    {
        if( owners.size() == 1 && owners.iterator().next() == SYSTEM_OWNER )
        {
            owners.clear();
        }
        
        final String ownersString = ( owners.size() == 0 ? null : encodeOwnersString( owners ) );
        return setOwners( cpe, ownersString );
    }

    private static IClasspathEntry setOwners( final IClasspathEntry cpe,
                                              final String owners )
    {
        final List<IClasspathAttribute> attrs = new ArrayList<IClasspathAttribute>();
        
        for( IClasspathAttribute attr : cpe.getExtraAttributes() )
        {
            if( ! attr.getName().equals( OWNER_PROJECT_FACETS_ATTR ) )
            {
                attrs.add( attr );
            }
        }
        
        if( owners != null )
        {
            attrs.add( JavaCore.newClasspathAttribute( OWNER_PROJECT_FACETS_ATTR, owners ) );
        }
        
        return new ClasspathEntry( cpe.getContentKind(), cpe.getEntryKind(), cpe.getPath(),
                                   cpe.getInclusionPatterns(), cpe.getExclusionPatterns(),
                                   cpe.getSourceAttachmentPath(), cpe.getSourceAttachmentRootPath(),
                                   cpe.getOutputLocation(), cpe.isExported(), cpe.getAccessRules(),
                                   cpe.combineAccessRules(), 
                                   attrs.toArray( new IClasspathAttribute[ attrs.size() ] ) );
    }

    private static String encodeOwnersString( final Set<Object> owners )
    {
        final StringBuilder buf = new StringBuilder();
        
        for( Object owner : owners )
        {
            if( buf.length() > 0 ) 
            {
                buf.append( ';' );
            }
            
            if( owner == SYSTEM_OWNER )
            {
                buf.append( "#system#" ); //$NON-NLS-1$
            }
            else
            {
                final IProjectFacet facet = (IProjectFacet) owner;
                buf.append( facet.getId() );
            }
        }
        
        return buf.toString();
    }
    
    private static Set<Object> decodeOwnersString( final String str )
    {
        final Set<Object> owners = new HashSet<Object>();
        final String[] split = str.split( ";" ); //$NON-NLS-1$
        
        for( int j = 0; j < split.length; j++ )
        {
            final String segment = split[ j ];
            
            if( segment.equals( "#system#" ) ) //$NON-NLS-1$
            {
                owners.add( SYSTEM_OWNER );
            }
            else
            {
                String facetId = segment;
                final int colon = facetId.indexOf( ':' );
                
                if( colon != -1 )
                {
                    facetId = facetId.substring( 0, colon );
                }
                
                owners.add( ProjectFacetsManager.getProjectFacet( facetId ) );
            }
        }
        
        return owners;
    }
    
    private static void convertLegacyMetadata( final IJavaProject project )
    
        throws CoreException
        
    {
        final IProject pj = project.getProject();
        final IFile legacyMetadataFile = pj.getFile( LEGACY_METADATA_FILE_NAME );
        
        if( legacyMetadataFile.exists() )
        {
            final ProjectScope scope = new ProjectScope( pj );
            final IEclipsePreferences pluginRoot = scope.getNode( FacetCorePlugin.PLUGIN_ID );
            final Preferences root = pluginRoot.node( "classpath.helper" ); //$NON-NLS-1$
            final Map<IPath,String> metadata = new HashMap<IPath,String>();
            
            final String[] keys;
            
            try
            {
                keys = root.childrenNames();
            }
            catch( BackingStoreException e )
            {
                throw new CoreException( FacetCorePlugin.createErrorStatus( e.getMessage(), e ) );
            }
            
            for( String key : keys )
            {
                final Preferences node = root.node( key );
                final String owners = node.get( "owners", null ); //$NON-NLS-1$
                
                if( owners != null )
                {
                    metadata.put( new Path( key.replaceAll( "::", "/" ) ), owners ); //$NON-NLS-1$ //$NON-NLS-2$
                }
            }
            
            if( ! metadata.isEmpty() )
            {
                final List<IClasspathEntry> cp = getProjectClasspath( project );
                boolean cpchanged = false;
                
                for( ListIterator<IClasspathEntry> itr = cp.listIterator(); itr.hasNext(); )
                {
                    final IClasspathEntry cpe = itr.next();
                    final String ownersString = metadata.get( cpe.getPath() );
                    
                    if( ownersString != null )
                    {
                        final Set<Object> owners = decodeOwnersString( ownersString );
                        itr.set( setOwners( cpe, encodeOwnersString( owners ) ) );
                        cpchanged = true;
                    }
                }
                
                if( cpchanged )
                {
                    setProjectClasspath( project, cp );
                }
            }
            
            legacyMetadataFile.delete( true, null );
        }
    }
    
    private static void validateClasspathEdit( final IJavaProject jproject )
    
        throws CoreException
        
    {
        final IWorkspace ws = ResourcesPlugin.getWorkspace();
        final IProject project = jproject.getProject();
        final IStatus st = ws.validateEdit( new IFile[] { project.getFile( ".classpath" ) }, IWorkspace.VALIDATE_PROMPT ); //$NON-NLS-1$
        
        if( st.getSeverity() == IStatus.ERROR )
        {
            throw new CoreException( st );
        }
    }
    
}
