/*******************************************************************************
 * Copyright (c) 2005, 2007 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:
 *     tyeung@bea.com - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.apt.core.internal.env;

import java.util.Arrays;
import java.util.List;

import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.SimpleName;

/*package*/ class EnvUtil {
	/**
     * Handling the following 2 cases
     * 1) For IProblems that does not have a starting and ending offset, 
     * place the problem at the class name. 
     * 
     * 2) For IProblems that does not have an ending offset, place the ending
     * offset at the end of the tightest ast node. 
     * We will only walk the ast once to determine the ending 
     * offsets of all the problems that do not have the information set. 
     */
    static void updateProblemLength(List<APTProblem> problems, CompilationUnit astUnit)
    {	
    	// for those problems that doesn't have an ending offset, figure it out by
    	// traversing the ast.
    	// we do it once just before we post the marker so we only have to walk the ast 
    	// once.
    	int count = 0;
    	int[] classNameRange = null;
    	for(IProblem problem : problems ){
			if( problem.getSourceStart() < 0 ){
				if( classNameRange == null )
					classNameRange = getClassNameRange(astUnit);
				problem.setSourceStart(classNameRange[0]);
				problem.setSourceEnd(classNameRange[1]);
				problem.setSourceLineNumber(classNameRange[2]);
			}
			if( problem.getSourceEnd() < 0 ){
				count ++;
			}
    	}
    		
		if( count > 0 ){
			if( astUnit != null ){
				final int[] startingOffsets = new int[count];
		    	int index = 0;
    			for( IProblem problem : problems ){
    				if( problem.getSourceEnd() < 0 )
    					startingOffsets[index++] = problem.getSourceStart();
    			}
    			
    			final EndingOffsetFinder lfinder = new EndingOffsetFinder(startingOffsets);
    			
    			astUnit.accept( lfinder );
    	    	
    	    	for(IProblem problem : problems ){
    				if( problem.getSourceEnd() < 0 ){
    					int startingOffset = problem.getSourceStart();
    					int endingOffset = lfinder.getEndingOffset(startingOffset);
    	    			if( endingOffset == 0 )
    	    				endingOffset = startingOffset;
    	    			problem.setSourceEnd(endingOffset-1);
    				}
    			}
			}
			else{
    			for(IProblem problem : problems){
    				// set the -1 source end to be the same as the source start.
    				if( problem.getSourceEnd() < problem.getSourceStart() )
    					problem.setSourceEnd(problem.getSourceStart());
    			}
    		}
		}	
    }
    
    /**
     * @param file
     * @return length 3 int array with the following information.
     * at index 0: contains the starting offset, always >= 0
     * at index 1: contains the ending offset, may be a negative number.
     * at index 2: the line number
     * 
     */
    private static int[] getClassNameRange(final CompilationUnit astUnit){
    	int[] startAndEnd = null;
    	if( astUnit != null){
    		@SuppressWarnings({"unchecked", "nls"})
    		final List<AbstractTypeDeclaration> topTypes = astUnit.types();
    		if( topTypes != null && topTypes.size() > 0 ){
    			final AbstractTypeDeclaration topType = topTypes.get(0);
    			startAndEnd = new int[3];
    			final SimpleName typename = topType.getName();
    			if( typename != null ){
    				startAndEnd[0] = typename.getStartPosition();
    				// ending offsets need to be exclusive.
    				startAndEnd[1] = startAndEnd[0] + typename.getLength() - 1;
    				startAndEnd[2] = astUnit.getLineNumber(typename.getStartPosition());
    				if( startAndEnd[2] < 1 )
    					startAndEnd[2] = 1;
    			}
    			else{
    				startAndEnd[0] = topType.getStartPosition();
    				// let case 2 in updateProblemLength() kicks in. 
    				startAndEnd[1] = -2;
    				startAndEnd[2] = astUnit.getLineNumber(topType.getStartPosition());
    				if( startAndEnd[2] < 1 )
    					startAndEnd[2] = 1;
    			}
    		}
    	}
    	if( startAndEnd == null )
    		// let case 2 in updateProblemLength() kicks in.
    		return new int[]{0, -2, 1};
    
    	return startAndEnd;
    }
    
    /**
     * Responsible for finding the ending offset of the ast node that has the tightest match 
     * for a given offset. This ast visitor can operator on an array of offsets in one pass.   
     * @author tyeung     
     */
    private static class EndingOffsetFinder extends ASTVisitor 
    {
    	private final int[] _sortedStartingOffset;
    	/** 
    	 * parallel to <code>_sortedOffsets</code> and contains 
    	 * the ending offset of the ast node that has the tightest match for the 
    	 * corresponding starting offset.
    	 */
    	private final int[] _endingOffsets;
    	
    	/**
    	 * @param offsets the array of offsets which will be sorted.
    	 * @throws IllegalArgumentException if <code>offsets</code> is <code>null</code>.
    	 */
    	private EndingOffsetFinder(int[] offsets)
    	{
    		if(offsets == null)
    			throw new IllegalArgumentException("argument cannot be null."); //$NON-NLS-1$
    		// sort the array first
    		Arrays.sort(offsets);
    	
    		// look for duplicates.		
    		int count = 0;	
    		for( int i=0, len=offsets.length; i<len; i++){
    			if( i > 0 && offsets[i-1] == offsets[i] )
    				continue;			
    			count ++;
    		}	
    	
    		if( count != offsets.length ){
    			_sortedStartingOffset = new int[count];
    	
    			int index = 0;
    			for( int i=0, len=offsets.length; i<len; i++){
    				if( i > 0 && offsets[i-1] == offsets[i] )
    					continue;
    				_sortedStartingOffset[index++] = offsets[i];
    			}		
    		}
    		else{
    			_sortedStartingOffset = offsets;
    		}
    		
    		_endingOffsets = new int[count];
    		for( int i=0; i<count; i++ )
    			_endingOffsets[i] = 0;
    	}
    	
    	public void preVisit(ASTNode node) 
    	{
    		final int startingOffset = node.getStartPosition();
    		final int endingOffset = startingOffset + node.getLength();
    		// starting offset is inclusive
    		int startIndex = Arrays.binarySearch(_sortedStartingOffset, startingOffset);
    		// ending offset is exclusive
    		int endIndex = Arrays.binarySearch(_sortedStartingOffset, endingOffset);
    		if( startIndex < 0 )
    			startIndex = - startIndex - 1;		
    		if( endIndex < 0 )
    			endIndex = - endIndex - 1;
    		else 
    			// endIndex needs to be exclusive and we want to 
    			// include the 'endIndex'th entry in our computation.
    			endIndex ++; 
    		if( startIndex >= _sortedStartingOffset.length )
    			return;
    		
    		for( int i=startIndex; i<endIndex; i++ ){    			
    			if( _endingOffsets[i] == 0 )
    				_endingOffsets[i] = endingOffset;
    			else if( endingOffset < _endingOffsets[i] )
    				_endingOffsets[i] = endingOffset;
    		}
    	}
    	
    	
    	public int getEndingOffset(final int startingOffset)
    	{
    		int index = Arrays.binarySearch(_sortedStartingOffset, startingOffset);
    		if( index == -1 ) return 0;
    		return _endingOffsets[index];
    	}
    }
}
