/******************************************************************************
 * Copyright (c) 2010 Oracle
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *    Konstantin Komissarchik - initial implementation and ongoing maintenance
 ******************************************************************************/

package org.eclipse.wst.common.project.facet.ui.internal.constraints;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.common.project.facet.core.IConstraint;
import org.eclipse.wst.common.project.facet.core.IGroup;
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.IVersionExpr;
import org.eclipse.wst.common.project.facet.core.internal.ProjectFacetRef;
import org.eclipse.wst.common.project.facet.core.util.internal.VersionExpr;

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

public final class ConstraintUtil
{
    private ConstraintUtil() {}
    
    public static ConstraintOperator convert( final IConstraint inputConstraint )
    {
        final IConstraint.Type inputConstraintType = inputConstraint.getType();
        
        if( inputConstraintType == IConstraint.Type.AND ||
            inputConstraintType == IConstraint.Type.OR )
        {
            final ConstraintOperator.Type outputConstraintType 
                = ( inputConstraintType == IConstraint.Type.AND 
                    ? ConstraintOperator.Type.AND : ConstraintOperator.Type.OR );
            
            final GroupingConstraintOperator outputConstraint
                = new GroupingConstraintOperator( outputConstraintType );
            
            for( Object child : inputConstraint.getOperands() )
            {
                outputConstraint.addChild( convert( (IConstraint) child ) );
            }
            
            return outputConstraint;
        }
        else if( inputConstraintType == IConstraint.Type.REQUIRES )
        {
            final Object firstOperand = inputConstraint.getOperand( 0 );

            final MultiFacetConstraintOperator outputConstraint
                = new MultiFacetConstraintOperator( ConstraintOperator.Type.REQUIRES_ONE );
            
            if( firstOperand instanceof IProjectFacet )
            {
                final IProjectFacet f = (IProjectFacet) firstOperand;
                final IVersionExpr vexpr = (IVersionExpr) inputConstraint.getOperand( 1 );
                outputConstraint.addProjectFacetRef( new ProjectFacetRef( f, vexpr ) );
            }
            else
            {
                final IGroup group = (IGroup) firstOperand;
                outputConstraint.addProjectFacetRefs( convertGroupToFacetRefs( group ) );
            }
            
            return outputConstraint;
        }
        else if( inputConstraintType == IConstraint.Type.CONFLICTS )
        {
            final Object firstOperand = inputConstraint.getOperand( 0 );

            final MultiFacetConstraintOperator outputConstraint
                = new MultiFacetConstraintOperator( ConstraintOperator.Type.CONFLICTS );
            
            if( firstOperand instanceof IProjectFacet )
            {
                final IProjectFacet f = (IProjectFacet) firstOperand;
                final IVersionExpr vexpr = (IVersionExpr) inputConstraint.getOperand( 1 );
                outputConstraint.addProjectFacetRef( new ProjectFacetRef( f, vexpr ) );
            }
            else
            {
                final IGroup group = (IGroup) firstOperand;
                outputConstraint.addProjectFacetRefs( convertGroupToFacetRefs( group ) );
            }
            
            return outputConstraint;
        }
        else
        {
            throw new IllegalStateException( inputConstraintType.name() );
        }
    }
    
    private static Collection<ProjectFacetRef> convertGroupToFacetRefs( final IGroup group )
    {
        final Map<IProjectFacet,List<IProjectFacetVersion>> members
            = new HashMap<IProjectFacet,List<IProjectFacetVersion>>();
        
        for( IProjectFacetVersion fv : group.getMembers() )
        {
            final IProjectFacet f = fv.getProjectFacet();
            List<IProjectFacetVersion> versions = members.get( f );
            
            if( versions == null )
            {
                versions = new ArrayList<IProjectFacetVersion>();
                members.put( f, versions );
            }
            
            versions.add( fv );
        }

        final List<ProjectFacetRef> facetRefs = new ArrayList<ProjectFacetRef>( members.size() );
        
        for( Map.Entry<IProjectFacet,List<IProjectFacetVersion>> entry : members.entrySet() )
        {
            final IProjectFacet f = entry.getKey();
            final List<IProjectFacetVersion> versions = entry.getValue();
            final String vexprString;
            
            if( versions.size() == f.getVersions().size() )
            {
                vexprString = IVersionExpr.WILDCARD_SYMBOL;
            }
            else
            {
                final StringBuilder buf = new StringBuilder();
                
                for( IProjectFacetVersion fv : versions )
                {
                    if( buf.length() > 0 )
                    {
                        buf.append( ',' );
                    }
                    
                    buf.append( fv.getVersionString() );
                }
                
                vexprString = buf.toString();
            }
            
            final IVersionExpr vexpr;
            
            try
            {
                vexpr = new VersionExpr<IProjectFacetVersion>( f, vexprString, null );
            }
            catch( CoreException e )
            {
                throw new RuntimeException( e );
            }
            
            facetRefs.add( new ProjectFacetRef( f, vexpr ) );
        }
        
        return facetRefs;
    }
    
    public static ConstraintOperator normalize( final ConstraintOperator input )
    {
        if( input instanceof GroupingConstraintOperator )
        {
            final List<ConstraintOperator> oldChildren = ( (GroupingConstraintOperator) input ).getChildren();
            final List<ConstraintOperator> newChildren = new ArrayList<ConstraintOperator>( oldChildren.size() );
            
            for( ConstraintOperator child : oldChildren )
            {
                newChildren.add( normalize( child ) );
            }
            
            if( input.getType() == ConstraintOperator.Type.AND )
            {
                // Can merge any REQUIRES_ALL operators under an AND. Note that a REQUIRES_ONE with
                // a single facet can be treated as REQUIRES_ALL.
                
                MultiFacetConstraintOperator firstRequiresAll = null;
                
                for( Iterator<ConstraintOperator> itr = newChildren.iterator(); itr.hasNext(); )
                {
                    final ConstraintOperator op = itr.next();
                    
                    if( op.getType() == ConstraintOperator.Type.REQUIRES_ALL ||
                        ( op.getType() == ConstraintOperator.Type.REQUIRES_ONE &&
                          ( (MultiFacetConstraintOperator) op ).getProjectFacetRefs().size() == 1 ) )
                    {
                        final MultiFacetConstraintOperator mfop = (MultiFacetConstraintOperator) op;
                        
                        if( firstRequiresAll == null )
                        {
                            firstRequiresAll = mfop;
                        }
                        else
                        {
                            firstRequiresAll.addProjectFacetRefs( mfop.getProjectFacetRefs() );
                            itr.remove();
                        }
                    }
                }
                
                if( firstRequiresAll != null && 
                    firstRequiresAll.getType() == ConstraintOperator.Type.REQUIRES_ONE && 
                    firstRequiresAll.getProjectFacetRefs().size() > 1 )
                {
                    firstRequiresAll.setType( ConstraintOperator.Type.REQUIRES_ALL );
                }
                
                // Can merge any CONFLICTS operators under an AND.
                
                MultiFacetConstraintOperator firstConflicts = null;
                
                for( Iterator<ConstraintOperator> itr = newChildren.iterator(); itr.hasNext(); )
                {
                    final ConstraintOperator op = itr.next();
                    
                    if( op.getType() == ConstraintOperator.Type.CONFLICTS )
                    {
                        final MultiFacetConstraintOperator mfop = (MultiFacetConstraintOperator) op;
                        
                        if( firstConflicts == null )
                        {
                            firstConflicts = mfop;
                        }
                        else
                        {
                            firstConflicts.addProjectFacetRefs( mfop.getProjectFacetRefs() );
                            itr.remove();
                        }
                    }
                }
            }
            else
            {
                // Can merge any REQUIRES_ONE operators under an OR that have only one child.
                
                MultiFacetConstraintOperator firstRequiresOne = null;
                
                for( Iterator<ConstraintOperator> itr = newChildren.iterator(); itr.hasNext(); )
                {
                    final ConstraintOperator op = itr.next();
                    
                    if( op.getType() == ConstraintOperator.Type.REQUIRES_ONE )
                    {
                        final MultiFacetConstraintOperator mfop = (MultiFacetConstraintOperator) op;
                        
                        if( firstRequiresOne == null )
                        {
                            firstRequiresOne = mfop;
                        }
                        else
                        {
                            firstRequiresOne.addProjectFacetRefs( mfop.getProjectFacetRefs() );
                            itr.remove();
                        }
                    }
                }
            }

            if( newChildren.size() == 1 )
            {
                return newChildren.get( 0 );
            }
            else
            {
                final GroupingConstraintOperator output = new GroupingConstraintOperator( input.getType() );
                output.addChildren( newChildren );
                return output;
            }
        }
        else
        {
            return input;
        }
    }
    
}
