/*
 * Created on Dec 8, 2003
 * 
 * To change the template for this generated file go to Window - Preferences -
 * Java - Code Generation - Code and Comments
 */
package org.eclipse.cdt.core.parser.tests;

import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Iterator;

import org.eclipse.cdt.core.parser.IParser;
import org.eclipse.cdt.core.parser.IParserLogService;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.ParserMode;
import org.eclipse.cdt.core.parser.ScannerInfo;
import org.eclipse.cdt.core.parser.ast.IASTClassSpecifier;
import org.eclipse.cdt.core.parser.ast.IASTCodeScope;
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode;
import org.eclipse.cdt.core.parser.ast.IASTField;
import org.eclipse.cdt.core.parser.ast.IASTFunction;
import org.eclipse.cdt.core.parser.ast.IASTMethod;
import org.eclipse.cdt.core.parser.ast.IASTNode;
import org.eclipse.cdt.core.parser.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.parser.ast.IASTVariable;
import org.eclipse.cdt.core.parser.ast.IASTNode.LookupKind;
import org.eclipse.cdt.core.parser.ast.IASTNode.LookupResult;
import org.eclipse.cdt.internal.core.parser.ParserLogService;

/**
 * @author jcamelon
 * 
 * To change the template for this generated type comment go to Window -
 * Preferences - Java - Code Generation - Code and Comments
 */
public class ContextualParseTest extends CompleteParseBaseTest {

	
	public ContextualParseTest(String name) {
		super(name);
	}

	protected IASTCompletionNode parse(String code, int offset)
		throws Exception {
		IParserLogService log = new ParserLogService();
		callback = new FullParseCallback();
		IParser parser = null;

		parser =
			ParserFactory.createParser(
				ParserFactory.createScanner(
					new StringReader(code),
					"completion-test",
					new ScannerInfo(),
					ParserMode.CONTEXTUAL_PARSE,
					ParserLanguage.CPP,
					callback,
					log),
				callback,
				ParserMode.CONTEXTUAL_PARSE,
				ParserLanguage.CPP,
				log);
		
		return parser.parse( offset );

	}

	public void testBaseCase_SimpleDeclaration() throws Exception
	{
		StringWriter writer = new StringWriter(); 
		writer.write( "class ABC " ); 
		writer.write( "{int x;}; " ); 
		writer.write( "AB\n\n" );

		IASTCompletionNode node = null;
		Iterator keywords = null;
		
		node = parse( writer.toString(), 21); 
		assertNotNull( node );
		assertNotNull( node.getCompletionPrefix() );
		assertEquals( node.getCompletionScope(), ((Scope)callback.getCompilationUnit()).getScope() );
		assertEquals( node.getCompletionPrefix(), "A");
		assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.VARIABLE_TYPE );
		keywords = node.getKeywords();
		assertFalse( keywords.hasNext() );

		node = parse( writer.toString(), 12); 
		assertNotNull( node );
		assertNotNull( node.getCompletionPrefix() );
		assertTrue( node.getCompletionScope() instanceof IASTClassSpecifier );
		assertEquals( node.getCompletionPrefix(), "i");
		assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.FIELD_TYPE );
		keywords = node.getKeywords(); 
		assertTrue( keywords.hasNext() );
		assertEquals( (String) keywords.next(), "inline");
		assertEquals( (String) keywords.next(), "int");
		assertFalse( keywords.hasNext() );
		
		node = parse( writer.toString(), 22); 
		assertNotNull( node );
		assertNotNull( node.getCompletionPrefix() );
		assertEquals( node.getCompletionScope(), ((Scope)callback.getCompilationUnit()).getScope() );
		assertEquals( node.getCompletionPrefix(), "AB");
		assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.VARIABLE_TYPE );
		keywords = node.getKeywords(); 
		assertFalse( keywords.hasNext() );
	
		node = parse( writer.toString(), 6); 
		assertNotNull( node );
		assertNotNull( node.getCompletionPrefix() );
		assertEquals( node.getCompletionScope(), ((Scope)callback.getCompilationUnit()).getScope() );
		assertEquals( node.getCompletionPrefix(), "");
		assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.USER_SPECIFIED_NAME );
		keywords = node.getKeywords(); 
		assertFalse( keywords.hasNext() );
	}
	
	public void testCompletionLookup_Unqualified() throws Exception
	{
		StringWriter writer = new StringWriter();
		writer.write( "int aVar; " );
		writer.write( "void foo( ) { " );
		writer.write( "   int anotherVar; " );
		writer.write( "   a " );
		writer.write( "} " );
		
		String code = writer.toString();
		
		for( int i = 0; i < 2; ++i )
		{	
			int index = ( i == 0 ? code.indexOf( " a " ) + 2 : code.indexOf( " a ") + 1 );
			
			IASTCompletionNode node = parse( code, index );	
			assertNotNull( node );
			
			String prefix = node.getCompletionPrefix();
			assertNotNull( prefix );
			assertTrue( node.getCompletionScope() instanceof IASTFunction );
			assertEquals( prefix, i == 0 ? "a" :"" );
			assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.STATEMENT_START );
			
			IASTNode.LookupKind[] kinds = new IASTNode.LookupKind[1];
			kinds[0] = IASTNode.LookupKind.ALL; 
			LookupResult result = node.getCompletionScope().lookup( prefix, kinds, node.getCompletionContext() );
			assertEquals( result.getPrefix(), prefix );
			
			Iterator iter = result.getNodes();
			
			IASTVariable anotherVar = (IASTVariable) iter.next();
			if( i != 0 )
			{
				IASTFunction foo = (IASTFunction) iter.next();
				assertEquals( foo.getName(), "foo");
			}
			IASTVariable aVar = (IASTVariable) iter.next();
					
			assertFalse( iter.hasNext() );
			assertEquals( anotherVar.getName(), "anotherVar" );
			assertEquals( aVar.getName(), "aVar" );
		}
	}
	
	public void testCompletionLookup_Qualified() throws Exception
	{
		StringWriter writer = new StringWriter();
		writer.write( "int aVar; " );
		writer.write( "struct D{ " );
		writer.write( "   int aField; " );
		writer.write( "   void aMethod(); " );
		writer.write( "}; " );
		writer.write( "void foo(){" );
		writer.write( "   D d; " );
		writer.write( "   d.a " );
		writer.write( "}\n" );
		
		String code = writer.toString();
		int index = code.indexOf( "d.a" );
		
		IASTCompletionNode node = parse( code, index + 3 );				
		assertNotNull( node );
		
		String prefix = node.getCompletionPrefix();
		assertNotNull( prefix );
		assertEquals( prefix, "a" );
		
		assertTrue( node.getCompletionScope() instanceof IASTFunction );
		assertEquals( node.getCompletionKind(), IASTCompletionNode.CompletionKind.MEMBER_REFERENCE );
		assertNotNull( node.getCompletionContext() );
		assertTrue( node.getCompletionContext() instanceof IASTClassSpecifier );
		
		IASTNode.LookupKind[] kinds = new IASTNode.LookupKind[1];
		kinds[0] = IASTNode.LookupKind.ALL; 
		LookupResult result = node.getCompletionScope().lookup( prefix, kinds, node.getCompletionContext() );
		assertEquals( result.getPrefix(), prefix );
		
		Iterator iter = result.getNodes();
		
		IASTMethod aMethod = null;
		IASTField aField = null;
		
		//we can't currently predict the order in this case
		for( int i = 1; i <= 2; i++ ){
			IASTNode astNode = (IASTNode) iter.next();
			if( astNode instanceof IASTMethod ){
				aMethod = (IASTMethod) astNode;
			} else{
				aField = (IASTField) astNode;
			}
		}
		
		assertFalse( iter.hasNext() );
		
		assertEquals( aMethod.getName(), "aMethod" );
		assertEquals( aField.getName(), "aField" );
	}
	
	public void testMemberCompletion_Arrow() throws Exception
	{
		StringWriter writer = new StringWriter();
		writer.write( "class A {" );
		writer.write( "   public:   void aPublicBaseMethod();" );
		writer.write( "   private:  void aPrivateBaseMethod();" );
		writer.write( "};" );
		writer.write( "class B : public A {" );
		writer.write( "   public:   void aMethod();" );
		writer.write( "};" );		
		writer.write( "void foo(){" );		
		writer.write( "   B * b = new B();" );		
		writer.write( "   b-> \n" );
		
		String code = writer.toString();
		int index = code.indexOf( "b->" );
		
		IASTCompletionNode node = parse( code, index + 3 );
		assertNotNull(node);
		assertEquals( node.getCompletionPrefix(), "" );
		
		assertEquals(node.getCompletionKind(), IASTCompletionNode.CompletionKind.MEMBER_REFERENCE);
		assertTrue(node.getCompletionScope() instanceof IASTFunction );
		assertEquals( ((IASTFunction)node.getCompletionScope()).getName(), "foo" ); 
		assertTrue(node.getCompletionContext() instanceof IASTClassSpecifier );
		assertEquals( ((IASTClassSpecifier)node.getCompletionContext()).getName(), "B" );
	}
	
	public void testMemberCompletion_Dot() throws Exception
	{
		StringWriter writer = new StringWriter();
		writer.write( "class A {" );
		writer.write( "   public:   void aPublicBaseMethod();" );
		writer.write( "   private:  void aPrivateBaseMethod();" );
		writer.write( "};" );
		writer.write( "class B : public A {" );
		writer.write( "   public:   void aMethod();" );
		writer.write( "};" );		
		writer.write( "void foo(){" );		
		writer.write( "   B b;" );		
		writer.write( "   b. \n" );
		
		String code = writer.toString();
		int index = code.indexOf( "b." );
		
		IASTCompletionNode node = parse( code, index + 2 );
		assertNotNull(node);
		assertEquals( node.getCompletionPrefix(), "" );
		
		assertEquals(node.getCompletionKind(), IASTCompletionNode.CompletionKind.MEMBER_REFERENCE);
		assertTrue(node.getCompletionScope() instanceof IASTFunction );
		assertEquals( ((IASTFunction)node.getCompletionScope()).getName(), "foo" ); 
		assertTrue(node.getCompletionContext() instanceof IASTClassSpecifier );
		assertEquals( ((IASTClassSpecifier)node.getCompletionContext()).getName(), "B" );
	}
	
	
	public void testCompletionLookup_Pointer() throws Exception{
		StringWriter writer = new StringWriter();
		writer.write( "class A {" );
		writer.write( "   public:   void aPublicBaseMethod();" );
		writer.write( "   private:  void aPrivateBaseMethod();" );
		writer.write( "};" );
		writer.write( "class B : public A {" );
		writer.write( "   public:   void aMethod();" );
		writer.write( "};" );		
		writer.write( "void foo(){" );		
		writer.write( "   B * b = new B();" );		
		writer.write( "   b->a \n" );
		
		for( int i = 0; i < 2; ++i )
		{	
			String code = writer.toString();
			
			int index;
			
			index = (i == 0 )? (code.indexOf( "b->a" )+4) :(code.indexOf( "b->") + 3);
			
			IASTCompletionNode node = parse( code, index);
			
			assertNotNull( node );
			String prefix = node.getCompletionPrefix();
			
			assertEquals( prefix, ( i == 0 ) ? "a" :"");
			
			assertTrue( node.getCompletionScope() instanceof IASTFunction );
			assertEquals( node.getCompletionKind(),  IASTCompletionNode.CompletionKind.MEMBER_REFERENCE );
			assertNotNull( node.getCompletionContext() );
			assertTrue( node.getCompletionContext() instanceof IASTClassSpecifier );
			
			IASTNode.LookupKind[] kinds = new IASTNode.LookupKind[1];
			kinds[0] = IASTNode.LookupKind.METHODS; 
			LookupResult result = node.getCompletionScope().lookup( prefix, kinds, node.getCompletionContext() );
			assertEquals( result.getPrefix(), prefix );
			
			Iterator iter = result.getNodes();
			IASTMethod method = (IASTMethod) iter.next();
			IASTMethod baseMethod = (IASTMethod) iter.next();
			
			assertFalse( iter.hasNext() );
			
			assertEquals( method.getName(), "aMethod" );
			assertEquals( baseMethod.getName(), "aPublicBaseMethod" );		
		}
	}
	
	public void testCompletionLookup_FriendClass_1() throws Exception{
		StringWriter writer = new StringWriter();
		writer.write( "class A {" );
		writer.write( "   private:  void aPrivateMethod();" );
		writer.write( "   friend class C;" );
		writer.write( "};" );
		
		writer.write( "class C {" );
		writer.write( "   void foo();" );
		writer.write( "};" );	
		
		writer.write( "void C::foo(){" );		
		writer.write( "   A a;" );		
		writer.write( "   a.a \n" );
		
		String code = writer.toString();
		int index = code.indexOf( "a.a" );
		
		IASTCompletionNode node = parse( code, index + 3 );
		
		assertNotNull( node );
		
		String prefix = node.getCompletionPrefix();
		assertEquals( prefix, "a" );
		
		assertTrue( node.getCompletionScope() instanceof IASTFunction );
		assertEquals( node.getCompletionKind(),  IASTCompletionNode.CompletionKind.MEMBER_REFERENCE );
		assertNotNull( node.getCompletionContext() );
		assertTrue( node.getCompletionContext() instanceof IASTClassSpecifier );
		
		LookupResult result = node.getCompletionScope().lookup( prefix, new IASTNode.LookupKind [] { IASTNode.LookupKind.METHODS }, node.getCompletionContext() );
		assertEquals( result.getPrefix(), prefix );
		
		Iterator iter = result.getNodes();
		assertTrue( iter.hasNext() );
		
		IASTMethod method = (IASTMethod) iter.next();
		
		assertFalse( iter.hasNext() );
		
		assertEquals( method.getName(), "aPrivateMethod" );
	}
	
	public void testCompletionLookup_FriendClass_2() throws Exception{
		StringWriter writer = new StringWriter();
		writer.write( "class C {" );
		writer.write( "   void foo();" );
		writer.write( "};" );		
		writer.write( "class A {" );
		writer.write( "   private:  void aPrivateMethod();" );
		writer.write( "   friend class C;" );
		writer.write( "};" );

		writer.write( "void C::foo(){" );		
		writer.write( "   A a;" );		
		writer.write( "   a.a \n" );
		
		String code = writer.toString();
		int index = code.indexOf( "a.a" );
		
		IASTCompletionNode node = parse( code, index + 3 );
		
		assertNotNull( node );
		
		String prefix = node.getCompletionPrefix();
		assertEquals( prefix, "a" );
		
		assertTrue( node.getCompletionScope() instanceof IASTFunction );
		assertEquals( node.getCompletionKind(),  IASTCompletionNode.CompletionKind.MEMBER_REFERENCE );
		assertNotNull( node.getCompletionContext() );
		assertTrue( node.getCompletionContext() instanceof IASTClassSpecifier );
		
		LookupResult result = node.getCompletionScope().lookup( prefix, new IASTNode.LookupKind [] { IASTNode.LookupKind.METHODS }, node.getCompletionContext() );
		assertEquals( result.getPrefix(), prefix );
		
		Iterator iter = result.getNodes();
		assertTrue( iter.hasNext() );
		
		IASTMethod method = (IASTMethod) iter.next();
		
		assertFalse( iter.hasNext() );
		
		assertEquals( method.getName(), "aPrivateMethod" );
	}
	
	
	public void testCompletionLookup_ParametersAsLocalVariables() throws Exception{
		StringWriter writer = new StringWriter();
		writer.write( "int foo( int aParameter ){" );
		writer.write( "   int aLocal;" );
		writer.write( "   if( aLocal != 0 ){" );		
		writer.write( "      int aBlockLocal;" );
		writer.write( "      a \n" );
		
		String code = writer.toString();
		int index = code.indexOf( " a " );
		
		IASTCompletionNode node = parse( code, index + 2 );
		
		assertNotNull( node );
		
		String prefix = node.getCompletionPrefix();
		assertEquals( prefix, "a" );
		
		assertTrue( node.getCompletionScope() instanceof IASTCodeScope );
		assertEquals( node.getCompletionKind(),  IASTCompletionNode.CompletionKind.STATEMENT_START );
		assertNull( node.getCompletionContext() );
				
		LookupResult result = node.getCompletionScope().lookup( prefix, new IASTNode.LookupKind [] { IASTNode.LookupKind.LOCAL_VARIABLES }, node.getCompletionContext() );
		assertEquals( result.getPrefix(), prefix );
		
		Iterator iter = result.getNodes();
				
		IASTVariable aBlockLocal = (IASTVariable) iter.next();
		IASTVariable aLocal = (IASTVariable) iter.next();
		IASTParameterDeclaration aParameter = (IASTParameterDeclaration) iter.next();
		
		assertFalse( iter.hasNext() );
		
		assertEquals( aBlockLocal.getName(), "aBlockLocal" );
		assertEquals( aLocal.getName(), "aLocal" );
		assertEquals( aParameter.getName(), "aParameter" );
	}
	
	public void testCompletionLookup_LookupKindTHIS() throws Exception{
		StringWriter writer = new StringWriter();
		writer.write( "int aGlobalVar;" );
		writer.write( "namespace NS { " );
		writer.write( "   int aNamespaceFunction(){}" );
		writer.write( "   class Base { " );
		writer.write( "      protected: int aBaseField;" );
		writer.write( "   };" );
		writer.write( "   class Derived : public Base {" );
		writer.write( "      int aMethod();" );
		writer.write( "   };" );
		writer.write( "}" );
		writer.write( "int NS::Derived::aMethod(){");
		writer.write( "   int aLocal;" );
		writer.write( "   a  ");

		String code = writer.toString();
		int index = code.indexOf( " a " );
		
		IASTCompletionNode node = parse( code, index + 2 );
		
		assertNotNull( node );
		
		assertEquals( node.getCompletionPrefix(), "a" );
		assertTrue( node.getCompletionScope() instanceof IASTMethod );
		
		LookupResult result = node.getCompletionScope().lookup( node.getCompletionPrefix(),
																new IASTNode.LookupKind[] { IASTNode.LookupKind.THIS },
																node.getCompletionContext() );
		
		assertEquals( result.getResultsSize(), 2 );
		
		Iterator iter = result.getNodes();
		IASTMethod method = (IASTMethod) iter.next();
		IASTField field = (IASTField) iter.next();
		assertFalse( iter.hasNext() );
		assertEquals( method.getName(), "aMethod" );
		assertEquals( field.getName(), "aBaseField" );
		
		result = node.getCompletionScope().lookup( node.getCompletionPrefix(),
												   new IASTNode.LookupKind[] { IASTNode.LookupKind.THIS, IASTNode.LookupKind.METHODS },
												   node.getCompletionContext() );
		
		assertEquals( result.getResultsSize(), 1 );
		iter = result.getNodes();
		method = (IASTMethod) iter.next();
		assertFalse( iter.hasNext() );
		assertEquals( method.getName(), "aMethod" );
	}
	
	public void testCompletionInConstructor() throws Exception
	{
		Writer writer = new StringWriter();
		writer.write("class SimpleTest{");
		writer.write("	public:");
		writer.write("SimpleTest();");
		writer.write("~SimpleTest();");
		writer.write("int a, b, c, aa, bb, cc, abc;");
		writer.write("};");
		writer.write("SimpleTest::~SimpleTest()");
		writer.write("{}");
		writer.write("SimpleTest::SimpleTest()");
		writer.write("{");
		writer.write("/**/a");
		writer.write("}");

		IASTCompletionNode node = parse( writer.toString(), writer.toString().indexOf("/**/a") + 5 );
		assertNotNull(node);
		assertEquals(node.getCompletionPrefix(), "a");
		assertTrue(node.getCompletionScope() instanceof IASTMethod);
		IASTMethod inquestion = (IASTMethod)node.getCompletionScope();
		assertEquals( inquestion.getName(), "SimpleTest");
		assertTrue(inquestion.isConstructor());
		
		assertEquals(node.getCompletionKind(), IASTCompletionNode.CompletionKind.STATEMENT_START );
		assertNull(node.getCompletionContext());
		LookupKind[] kinds = new LookupKind[ 1 ];
		kinds[0] = LookupKind.FIELDS;
		
		LookupResult result = inquestion.lookup( "a", kinds, null );
		assertEquals(result.getResultsSize(), 3 );
	}
	
	public void testCompletionInDestructor() throws Exception
	{
		Writer writer = new StringWriter();
		writer.write("class SimpleTest{");
		writer.write("	public:");
		writer.write("SimpleTest();");
		writer.write("~SimpleTest();");
		writer.write("int a, b, c, aa, bb, cc, abc;");
		writer.write("};");
		writer.write("SimpleTest::SimpleTest()");
		writer.write("{}");
		writer.write("SimpleTest::~SimpleTest()");
		writer.write("{");
		writer.write("/**/a");
		writer.write("}");

		IASTCompletionNode node = parse( writer.toString(), writer.toString().indexOf("/**/a") + 5 );
		assertNotNull(node);
		assertEquals(node.getCompletionPrefix(), "a");
		assertTrue(node.getCompletionScope() instanceof IASTMethod);
		IASTMethod inquestion = (IASTMethod)node.getCompletionScope();
		assertEquals( inquestion.getName(), "~SimpleTest");
		assertTrue(inquestion.isDestructor());
		
		assertEquals(node.getCompletionKind(), IASTCompletionNode.CompletionKind.STATEMENT_START );
		assertNull(node.getCompletionContext());
		LookupKind[] kinds = new LookupKind[ 1 ];
		kinds[0] = LookupKind.FIELDS;
		
		LookupResult result = inquestion.lookup( "a", kinds, null );
		assertEquals(result.getResultsSize(), 3 );
	}
}
