/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute and Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 *
 * Contributors:
 * 	  Fraunhofer FIRST - Initial API and implementation
 * 	  Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.tests.selection;

import org.eclipse.jdt.core.tests.compiler.parser.AbstractSelectionTest;

/**
 * Testing OT-specific selections within a team class.
 *
 * @author jwloka
 * @version $Id: OTSpecificSelectionWithinTeamTests.java 23494 2010-02-05 23:06:44Z stephan $
 */
public class OTSpecificSelectionWithinTeamTests extends AbstractSelectionTest
{
	public OTSpecificSelectionWithinTeamTests(String testName)
	{
		super(testName);
	}

	//type declarations
	//NOTE(gbr): type declarations are tested differently than type references
	//(see org.eclipse.objectteams.otdt.tests.selection.codeselect.CodeSelectionTests).

//	/**
//	 * Select team class name of team class declaration.
//	 */
//	public void test01()
//	{
//		String str =
//		    "public team class T1 {\n" +
//			"\n" +
//			"}\n";
//
//		String selectionStartBehind = "class ";
//		String selectionEndBehind = "T1";
//
//		String expectedCompletionNodeToString = "<SelectOnType:T1>";
//		String completionIdentifier = "T1";
//		String expectedUnitDisplayString =
//			"public team class <SelectOnType:T1> {\n" +
//			"\n" +
//			"	public T1() {\n" +
//			"	\n" +
//			"	}\n" +
//			"}\n";
//
//		String expectedReplacedSource = "T1";
//		String testName = "<select team class name of team class declaration>";
//
//		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
//		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;
//
//		this.checkDietParse(
//			str.toCharArray(),
//			selectionStart,
//			selectionEnd,
//			expectedCompletionNodeToString,
//			expectedUnitDisplayString,
//			completionIdentifier,
//			expectedReplacedSource,
//			testName);
//	}
//
//	/**
//	 * Select team class name of nested team class declaration.
//	 */
//	public void test02()
//	{
//		String str =
//			"public team class T1 {\n" +
//			"{\n" +
//			"	public team class TR1 {\n" +
//			"	\n" +
//			"	}\n" +
//			"}\n";
//
//		String selectionStartBehind = "\n{\n\n\tpublic team class ";
//		String selectionEndBehind = "TR1";
//
//		String expectedCompletionNodeToString = "<SelectOnType:TR1>";
//		String completionIdentifier = "TR1";
//		String expectedUnitDisplayString =
//			"public team class T1 {\n" +
//			"\n" +
//			"	public T1() {\n" +
//			"	\n" +
//			"	}\n" +
//			"	public team class <SelectOnType:TR1> {\n" +
//			"	\n" +
//			"	}\n" +
//			"}\n";
//
//		String expectedReplacedSource = "TR1";
//		String testName = "<select team class name of nested team class declaration>";
//
//		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
//		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;
//
//		this.checkDietParse(
//			str.toCharArray(),
//			selectionStart,
//			selectionEnd,
//			expectedCompletionNodeToString,
//			expectedUnitDisplayString,
//			completionIdentifier,
//			expectedReplacedSource,
//			testName);
//}

	//type references
	/**
	 * Select team class name of anchor type.
	 */
	public void test03()
	{
		String str =
			"public team class T1 {\n" +
			"  T1 t1 = new T1();\n" +
			"  t1.R1 r1;\n" +
			"  public class R1 {\n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "T1 {\n  ";
		String selectionEndBehind = "  T1";

		String expectedCompletionNodeToString = "<SelectOnType:T1>";
		String completionIdentifier = "T1";
		String expectedUnitDisplayString =
			"public team class T1 {\n" +
			"  public role class R1 {\n" +
			"  }\n" +
			"  <SelectOnType:T1> t1 = new T1();\n" +
			"  t1.R1 r1;\n" +
			"  public T1() {\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "T1";
		String testName = "<select team class name of anchored type>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkDietParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	/**
	 * Select team class name in <code>within</code>-expression.
	 */
	public void test04()
	{
		String str =
		    "public team class T1 {\n" +
		    "  void foo() {\n" +
			"    within (new T2()) {\n" +
			"    }\n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "new ";
		String selectionEndBehind = "T2";

		String expectedCompletionNodeToString = "<SelectOnAllocationExpression:new T2()>";
		String completionIdentifier = "T2";
		String expectedUnitDisplayString =
			"public team class T1 {\n" +
			"  public T1() {\n" +
			"  }\n" +
		    "  void foo() {\n" +
			"    <SelectOnAllocationExpression:new T2()>;\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "new T2()";
		String testName = "<select team instantiation in within expression>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkMethodParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	/**
	 * Select team class name in <code>playedBy</code>-relation.
	 */
	public void test05()
	{
		String str =
		    "public team class T1 {\n" +
			"  public class R1 playedBy T2 {\n" +
			"  \n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "playedBy ";
		String selectionEndBehind = "T2";

		String expectedCompletionNodeToString = "<SelectOnType:T2>";
		String completionIdentifier = "T2";
		String expectedUnitDisplayString =
			"public team class T1 {\n" +
			"  public role class R1 playedBy <SelectOnType:T2> {\n" +
			"  }\n" +
			"  public T1() {\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "T2";
		String testName = "<select team class name in playedBy relation>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkDietParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	/**
	 * Select team class name in import declaration.
	 */
	public void test06()
	{
		String str =
		    "import x.y.T2\n" +
		    "public team class T1 {\n" +
			"  public class R1 playedBy T2 {\n" +
			"  \n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "y.";
		String selectionEndBehind = "y.T2";

		String expectedCompletionNodeToString = "<SelectOnImport:x.y.T2>";
		String completionIdentifier = "T2";
		String expectedUnitDisplayString =
		    "import <SelectOnImport:x.y.T2>;\n" +
			"public team class T1 {\n" +
			"  public role class R1 playedBy T2 {\n" +
			"  }\n" +
			"  public T1() {\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "x.y.T2";
		String testName = "<select team class name in import declaration>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkDietParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	/**
	 * Select team class name in lifting method (declared lifting).
	 * The team class is the role class.
	 */
	public void test07()
	{
		String str =
		    "public team class T1 {\n" +
			"  public void m1(B1 as T2 arg) {\n" +
			"  }\n" +
			"  public team class T2 playedBy B1 {\n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "as ";
		String selectionEndBehind = "as T2";

		String expectedCompletionNodeToString = "<SelectOnType:T2>";
		String completionIdentifier = "T2";
		String expectedUnitDisplayString =
		    "public team class T1 {\n" +
			"  public role team class T2 playedBy B1 {\n" +
			"  }\n" +
			"  public T1() {\n" +
			"  }\n" +
			"  public void m1(B1 as <SelectOnType:T2> arg) {\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "T2";
		String testName = "<select team class name in lifting method>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkDietParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	/**
	 * Select team class name in lifting method (declared lifting).
	 * The team class is the base class.
	 */
	public void test08()
	{
		String str =
		    "public team class T1 {\n" +
			"  public void m1(T2 as R1 arg) {\n" +
			"  }\n" +
			"  public class R1 playedBy T2 {\n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "(";
		String selectionEndBehind = "(T2";

		String expectedCompletionNodeToString = "<SelectOnType:T2>";
		String completionIdentifier = "T2";
		String expectedUnitDisplayString =
		    "public team class T1 {\n" +
			"  public role class R1 playedBy T2 {\n" +
			"  }\n" +
			"  public T1() {\n" +
			"  }\n" +
			"  public void m1(<SelectOnType:T2> as R1 arg) {\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "T2";
		String testName = "<select team class name in lifting method>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkDietParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}


	/**
	 * Select team class name in team-level guard.
	 */
	public void test09()
	{
		String str =
			"public class T2 {\n" +
		    "  public team class T1 when (T2.this != null) {\n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "(";
		String selectionEndBehind = "(T2";

		String expectedCompletionNodeToString = "<SelectOnType:T2>";
		String completionIdentifier = "T2";
		String expectedUnitDisplayString =
			"public class T2 {\n" +
		    "  public team class T1 {\n" +
			"    public T1() {\n" +
			"    }\n" +
			"    protected synchronized boolean _OT$when() {\n" +
			"      return (<SelectOnType:T2>.this != null);\n" +
			"    }\n" +
			"  }\n" +
			"  public T2() {\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "T2";
		String testName = "<select team class name in team-level guard>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkDietParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	//TODO(gbr) select team class name in team package

	//method declarations
	//NOTE(gbr): method declarations are tested differently than method references
	//(see org.eclipse.objectteams.otdt.tests.selection.codeselect.CodeSelectionTests).

	//method references
	/**
	 * Select team method name in team-level method.
	 */
	public void test10()
	{
		String str =
		    "public team class T1 {\n" +
		    "  public void m1(int x) {\n" +
			"  }\n" +
			"  public void m2(int x) {\n" +
			"    m1(x);\n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "m2(int x) {\n    ";
		String selectionEndBehind = "    m1";

		String expectedCompletionNodeToString = "<SelectOnMessageSend:m1(x)>";
		String completionIdentifier = "m1";
		String expectedUnitDisplayString =
		    "public team class T1 {\n" +
			"  public T1() {\n" +
			"  }\n" +
			"  public void m1(int x) {\n" +
			"  }\n" +
			"  public void m2(int x) {\n" +
			"    <SelectOnMessageSend:m1(x)>;\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "m1(x)";
		String testName = "<select team method name in team-level method>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkMethodParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	/**
	 * Select team method name in <code>within</code> block.
	 */
	public void test11()
	{
		String str =
		    "public team class T1 {\n" +
		    "  public void m1() {\n" +
			"    within (new T1()) {\n" +
			"      m1();\n" +
			"    }\n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "new T1()) {\n      ";
		String selectionEndBehind = "      m1";

		String expectedCompletionNodeToString = "<SelectOnMessageSend:m1()>";
		String completionIdentifier = "m1";
		String expectedUnitDisplayString =
			"public team class T1 {\n" +
			"  public T1() {\n" +
			"  }\n" +
		    "  public void m1() {\n" +
			"    {\n" +
			"      <SelectOnMessageSend:m1()>;\n" +
			"    }\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "m1()";
		String testName = "<select team method name in within-block>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkMethodParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	/**
	 * Select team method name in team-level guard.
	 */
	public void test12()
	{
		String str =
		    "public team class T1 when (this.isValid()) {\n" +
		    "  public boolean isValid() {\n" +
		    "    return true;" +
		    "  }\n" +
			"}\n";

		String selectionStartBehind = "when (this.";
		String selectionEndBehind = "this.isValid";

		String expectedCompletionNodeToString = "<SelectOnMessageSend:this.isValid()>";
		String completionIdentifier = "isValid";
		String expectedUnitDisplayString =
		    "public team class T1 {\n" +
			"  public T1() {\n" +
			"  }\n" +
		    "  public boolean isValid() {\n" +
		    "  }\n" +
			"  protected synchronized boolean _OT$when() {\n" +
			"    return <SelectOnMessageSend:this.isValid()>;\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "this.isValid()";
		String testName = "<select team method name in team-level guard>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkDietParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	//field declarations
	//NOTE(gbr): field declarations are tested differently than field references
	//(see org.eclipse.objectteams.otdt.tests.selection.codeselect.CodeSelectionTests).

	//field references
	/**
	 * Select team field name in team-level method.
	 */
	public void test13()
	{
		String str =
		    "public team class T1 {\n" +
		    "  private int f;\n" +
			"  public void m2(int y) {\n" +
			"    f = y;\n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "m2(int y) {\n    ";
		String selectionEndBehind = "    f";

		String expectedCompletionNodeToString = "<SelectOnName:f>";
		String completionIdentifier = "f";
		String expectedUnitDisplayString =
		    "public team class T1 {\n" +
		    "  private int f;\n" +
			"  public T1() {\n" +
			"  }\n" +
			"  public void m2(int y) {\n" +
			"    <SelectOnName:f>;\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "f";
		String testName = "<select team field name in team-level method>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkMethodParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	/**
	 * Select team field name in <code>within</code> block.
	 */
	public void test14()
	{
		String str =
		    "public team class T1 {\n" +
		    "  private int f;\n" +
		    "  void foo() {\n" +
		    "    within (new T1()) {\n" +
			"      f++;\n" +
			"    }\n" +
			"  }\n" +
			"}\n";

		String selectionStartBehind = "new T1()) {\n      ";
		String selectionEndBehind = "      f";

		String expectedCompletionNodeToString = "<SelectOnName:f>";
		String completionIdentifier = "f";
		String expectedUnitDisplayString =
			"public team class T1 {\n" +
		    "  private int f;\n" +
			"  public T1() {\n" +
			"  }\n" +
		    "  void foo() {\n" +
			"    {\n" +
			"      <SelectOnName:f>;\n" +
			"    }\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "f";
		String testName = "<select team field name in within-block>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkMethodParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

	/**
	 * Select team field name in team-level guard.
	 */
	public void test15()
	{
		String str =
		    "public team class T1 when (this.f != 0) {\n" +
		    "  private int f;\n" +
			"}\n";

		String selectionStartBehind = "(this.";
		String selectionEndBehind = "this.f";

		String expectedCompletionNodeToString = "<SelectionOnFieldReference:this.f>";
		String completionIdentifier = "f";
		String expectedUnitDisplayString =
		    "public team class T1 {\n" +
		    "  private int f;\n" +
			"  public T1() {\n" +
			"  }\n" +
			"  protected synchronized boolean _OT$when() {\n" +
			"    return (<SelectionOnFieldReference:this.f> != 0);\n" +
			"  }\n" +
			"}\n";

		String expectedReplacedSource = "this.f";
		String testName = "<select team field name in team-level guard>";

		int selectionStart = str.indexOf(selectionStartBehind) + selectionStartBehind.length();
		int selectionEnd = str.indexOf(selectionEndBehind) + selectionEndBehind.length() - 1;

		this.checkDietParse(
			str.toCharArray(),
			selectionStart,
			selectionEnd,
			expectedCompletionNodeToString,
			expectedUnitDisplayString,
			completionIdentifier,
			expectedReplacedSource,
			testName);
	}

}