/*******************************************************************************
 * Copyright (c) 2020, 2022 IBM Corporation and others.
 *
 * 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
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.core.tests.dom;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.AST;
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.Expression;
import org.eclipse.jdt.core.dom.GuardedPattern;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.Pattern;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypePattern;

import junit.framework.Test;

public class ASTConverter_PreviewTest extends ConverterTestSetup {

	ICompilationUnit workingCopy;

	public void setUpSuite() throws Exception {
		super.setUpSuite();
		this.ast = AST.newAST(getASTLatest(), false);
		this.currentProject = getJavaProject("Converter_17");
		if (this.ast.apiLevel() == AST.JLS18) {
			this.currentProject.setOption(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_18);
			this.currentProject.setOption(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_18);
			this.currentProject.setOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_18);
			this.currentProject.setOption(JavaCore.COMPILER_PB_ENABLE_PREVIEW_FEATURES, JavaCore.ENABLED);
			this.currentProject.setOption(JavaCore.COMPILER_PB_REPORT_PREVIEW_FEATURES, JavaCore.IGNORE);

		}
	}

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

	public static Test suite() {
		return buildModelTestSuite(ASTConverter_PreviewTest.class);
	}

	static int getASTLatest() {
		return AST.getJLSLatest();
	}
	protected void tearDown() throws Exception {
		super.tearDown();
		if (this.workingCopy != null) {
			this.workingCopy.discardWorkingCopy();
			this.workingCopy = null;
		}
	}

	private void printJREError() {
		System.err.println("Test "+getName()+" requires a JRE 18");
	}

	@SuppressWarnings("rawtypes")
	public void testTypePattern() throws CoreException {
		if (!isJRE18) {
			printJREError();
			return;
		}
		String contents = "public class X {\n" +
				"void foo(Object o) {\n" +
				"	switch (o) {\n" +
			    "		case Integer i  -> System.out.println(i.toString());\n" +
			    "		case String s   -> System.out.println(s);\n" +
			    "		default       	-> System.out.println(o.toString());\n" +
			    "	}\n" +
			    "}\n" +
				"\n" +
				"}\n";
		this.workingCopy = getWorkingCopy("/Converter_17/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0, 0);
		assertEquals("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
		List statements = ((SwitchStatement)node).statements();
		assertEquals("incorrect no of statements", 6, statements.size());
		SwitchCase caseInteger = (SwitchCase) statements.get(0);
		Expression typePattern = (Expression)caseInteger.expressions().get(0);
		assertEquals("Type Pattern", typePattern.getNodeType(), ASTNode.TYPE_PATTERN);
		SingleVariableDeclaration patternVariable = ((TypePattern)typePattern).getPatternVariable();
		assertEquals("Type Pattern Integer", "Integer", patternVariable.getType().toString());
		SingleVariableDeclaration patternVariable2 = ((TypePattern)typePattern).patternVariables().get(0);
		assertEquals(patternVariable, patternVariable2);

		SwitchCase caseString = (SwitchCase) statements.get(2);
		typePattern = (Expression)caseString.expressions().get(0);
		assertEquals("Type Pattern", typePattern.getNodeType(), ASTNode.TYPE_PATTERN);
		patternVariable = ((TypePattern)typePattern).getPatternVariable();
		assertEquals("Type Pattern Integer", "String", patternVariable.getType().toString());
		patternVariable2 = ((TypePattern)typePattern).patternVariables().get(0);
		assertEquals(patternVariable, patternVariable2);

		SwitchCase caseDefault = (SwitchCase) statements.get(4);
		assertTrue("Default case", caseDefault.isDefault());

	}

	@SuppressWarnings("rawtypes")
	public void testGuardedPattern() throws CoreException {
		if (!isJRE18) {
			printJREError();
			return;
		}
		String contents = "public class X {\n" +
				"void foo(Object o) {\n" +
				"	switch (o) {\n" +
			    "		case Integer i  && (i.intValue() > 10)   -> System.out.println(\"Greater than 10 \");\n" +
			    "		case String s && s.equals(\"ff\")   -> System.out.println(s);\n" +
			    "		default       	-> System.out.println(o.toString());\n" +
			    "	}\n" +
			    "}\n" +
				"\n" +
				"}\n";
		this.workingCopy = getWorkingCopy("/Converter_17/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0, 0);
		assertEquals("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
		List statements = ((SwitchStatement)node).statements();
		assertEquals("incorrect no of statements", 6, statements.size());
		SwitchCase caseInteger = (SwitchCase) statements.get(0);
		Expression guardedPattern = (Expression)caseInteger.expressions().get(0);
		assertEquals("Guarded Pattern", guardedPattern.getNodeType(), ASTNode.GUARDED_PATTERN);
		Pattern pattern = ((GuardedPattern)guardedPattern).getPattern();
		SingleVariableDeclaration patternVariable = ((TypePattern)pattern).getPatternVariable();
		assertEquals("Type Pattern Integer", "Integer", patternVariable.getType().toString());
		SingleVariableDeclaration patternVariable2 = ((TypePattern)pattern).patternVariables().get(0);
		assertEquals(patternVariable, patternVariable2);
		Expression expression = ((GuardedPattern)guardedPattern).getExpression();
		Expression expression2 = ((ParenthesizedExpression)expression).getExpression();
		assertEquals("Infix expression", "i.intValue() > 10", expression2.toString());


		SwitchCase caseString = (SwitchCase) statements.get(2);
		guardedPattern = (Expression)caseString.expressions().get(0);
		assertEquals("Guarded Pattern", guardedPattern.getNodeType(), ASTNode.GUARDED_PATTERN);
		pattern = ((GuardedPattern)guardedPattern).getPattern();
		patternVariable = ((TypePattern)pattern).getPatternVariable();
		assertEquals("Type Pattern String", "String", patternVariable.getType().toString());
		patternVariable2 = ((TypePattern)pattern).patternVariables().get(0);
		assertEquals(patternVariable, patternVariable2);
		expression = ((GuardedPattern)guardedPattern).getExpression();
		assertEquals("Infix expression", "s.equals(\"ff\")",expression.toString());

		SwitchCase caseDefault = (SwitchCase) statements.get(4);
		assertTrue("Default case", caseDefault.isDefault());

	}

	@SuppressWarnings("rawtypes")
	public void testParenthesizedExpressionPattern() throws CoreException {
		if (!isJRE18) {
			printJREError();
			return;
		}
		String contents = "public class X {\n" +
				"void foo(Object o) {\n" +
				"	switch (o) {\n" +
			    "		case (Integer i)  : System.out.println(i.toString());\n" +
			    "		default       	  : System.out.println(o.toString());\n" +
			    "	}\n" +
			    "}\n" +
				"\n" +
				"}\n";
		this.workingCopy = getWorkingCopy("/Converter_17/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0, 0);
		assertEquals("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
		List statements = ((SwitchStatement)node).statements();
		assertEquals("incorrect no of statements", 4, statements.size());
		SwitchCase caseInteger = (SwitchCase) statements.get(0);
		Expression parenthesizedExpression = (Expression)caseInteger.expressions().get(0);
		assertEquals("Parenthesized Expression", parenthesizedExpression.getNodeType(), ASTNode.PARENTHESIZED_EXPRESSION);
		Expression targetPattern = ((ParenthesizedExpression)parenthesizedExpression).getExpression();
		assertEquals("Type Pattern", targetPattern.getNodeType(), ASTNode.TYPE_PATTERN);
		SingleVariableDeclaration patternVariable = ((TypePattern)targetPattern).getPatternVariable();
		assertEquals("Type Pattern Integer", "Integer", patternVariable.getType().toString());
		SingleVariableDeclaration patternVariable2 = ((TypePattern)targetPattern).patternVariables().get(0);
		assertEquals(patternVariable, patternVariable2);

		SwitchCase caseDefault = (SwitchCase) statements.get(2);
		assertTrue("Default case", caseDefault.isDefault());

	}

	@SuppressWarnings("rawtypes")
	public void testNullPattern() throws CoreException {
		if (!isJRE18) {
			printJREError();
			return;
		}
		String contents = "public class X {\n" +
				"void foo(Object o) {\n" +
				"	switch (o) {\n" +
			    "		case Integer i  : System.out.println(i.toString());\n" +
				"						  break;\n" +
			    "		case null  		: System.out.println(\"null\");\n" +
			    "		default       	: System.out.println(o.toString());\n" +
			    "	}\n" +
			    "}\n" +
				"\n" +
				"}\n";
		this.workingCopy = getWorkingCopy("/Converter_17/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0, 0);
		assertEquals("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
		List statements = ((SwitchStatement)node).statements();
		assertEquals("incorrect no of statements", 7, statements.size());
		SwitchCase caseInteger = (SwitchCase) statements.get(3);
		Expression nullExpression = (Expression)caseInteger.expressions().get(0);
		assertEquals("Null Expression", nullExpression.getNodeType(), ASTNode.NULL_LITERAL);
	}

	@SuppressWarnings("rawtypes")
	public void testCaseDefaultExpressionPattern() throws CoreException {
		if (!isJRE18) {
			printJREError();
			return;
		}
		String contents = "public class X {\n" +
				"void foo(Object o) {\n" +
				"	switch (o) {\n" +
			    "		case Integer i  : System.out.println(i.toString());\n" +
			    "		case default    : System.out.println(o.toString());\n" +
			    "	}\n" +
			    "}\n" +
				"\n" +
				"}\n";
		this.workingCopy = getWorkingCopy("/Converter_17/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		node = getASTNode(compilationUnit, 0, 0, 0);
		assertEquals("Switch statement", node.getNodeType(), ASTNode.SWITCH_STATEMENT);
		List statements = ((SwitchStatement)node).statements();
		assertEquals("incorrect no of statements", 4, statements.size());
		SwitchCase caseDefault = (SwitchCase) statements.get(2);
		Expression caseDefaultExpression = (Expression) caseDefault.expressions().get(0);
		assertEquals("Case Default Expression",caseDefaultExpression.getNodeType() , ASTNode.CASE_DEFAULT_EXPRESSION);


	}

	public void testBug575250() throws CoreException {
		if (!isJRE18) {
			System.err.println("Test "+getName()+" requires a JRE 18");
			return;
		}
		String contents = "public class X {\n" +
				"  static void foo(Object o) {\n" +
				"    switch (o) {\n" +
				"      case (Integer i_1): System.out.println(\"Integer\");\n" +
				"      default: System.out.println(\"Object\");" +
				"    }\n" +
				"  }\n" +
				"}\n";
		this.workingCopy = getWorkingCopy("/Converter_17/src/X.java", true/*resolve*/);
		ASTNode node = buildAST(
			contents,
			this.workingCopy);
		assertEquals("Not a compilation unit", ASTNode.COMPILATION_UNIT, node.getNodeType());
		CompilationUnit compilationUnit = (CompilationUnit) node;
		assertProblemsSize(compilationUnit, 0);
		List<AbstractTypeDeclaration> types = compilationUnit.types();
		assertEquals("incorrect types", types.size(), 1);
		AbstractTypeDeclaration type = types.get(0);
		assertTrue("should be a type", type instanceof TypeDeclaration);
		TypeDeclaration typeDecl = (TypeDeclaration)type;
		final List<TypePattern> result = new ArrayList<>();
		typeDecl.accept(new ASTVisitor() {
			public boolean visit(TypePattern n) {
				result.add(n);
				return true;
			}
		});
		assertEquals("incorrect no of patterns", 1, result.size());
		TypePattern typePattern = result.get(0);
		assertNotNull("pattern is null", typePattern);
		int start = contents.indexOf("Integer");
		int length = "Integer i_1".length();
		assertEquals("wrong source range", typePattern.getStartPosition(), start);
		assertEquals("wrong source range", typePattern.getLength(), length);

		SingleVariableDeclaration patternVariable = typePattern.getPatternVariable();
		assertEquals("wrong source range", patternVariable.getStartPosition(), start);
		assertEquals("wrong source range", patternVariable.getLength(), length);

		Type type2 = patternVariable.getType();
		assertEquals("wrong source range", type2.getStartPosition(), start);
		assertEquals("wrong source range", type2.getLength(), "Integer".length());

		SimpleName name = patternVariable.getName();
		start = contents.indexOf("i_1");
		assertEquals("wrong source range", name.getStartPosition(), start);
		assertEquals("wrong source range", name.getLength(), "i_1".length());
	}
}
