/*******************************************************************************
 * Copyright (c) 2000, 2020 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.ui.tests.refactoring;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.ByteArrayInputStream;
import java.util.Collection;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.eclipse.team.core.RepositoryProvider;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourceAttributes;

import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.CopyRefactoring;
import org.eclipse.ltk.core.refactoring.participants.MoveRefactoring;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.refactoring.IJavaRefactorings;
import org.eclipse.jdt.core.refactoring.descriptors.RenameJavaElementDescriptor;

import org.eclipse.jdt.internal.core.refactoring.descriptors.RefactoringSignatureDescriptorFactory;
import org.eclipse.jdt.internal.corext.refactoring.reorg.IReorgPolicy.ICopyPolicy;
import org.eclipse.jdt.internal.corext.refactoring.reorg.IReorgPolicy.IMovePolicy;
import org.eclipse.jdt.internal.corext.refactoring.reorg.JavaCopyProcessor;
import org.eclipse.jdt.internal.corext.refactoring.reorg.JavaMoveProcessor;
import org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgDestinationFactory;
import org.eclipse.jdt.internal.corext.refactoring.reorg.ReorgPolicyFactory;

import org.eclipse.jdt.ui.tests.refactoring.ccp.MockReorgQueries;
import org.eclipse.jdt.ui.tests.refactoring.infra.RefactoringTestRepositoryProvider;
import org.eclipse.jdt.ui.tests.refactoring.rules.Java1d5Setup;


public class ValidateEditTests extends GenericRefactoringTest {

	public ValidateEditTests() {
		rts= new Java1d5Setup();
	}

	@Before
	public void setUp() throws Exception {
		RepositoryProvider.map(getRoot().getJavaProject().getProject(), RefactoringTestRepositoryProvider.PROVIDER_ID);
	}

	@After
	public void tearDown() throws Exception {
		RepositoryProvider.unmap(getRoot().getJavaProject().getProject());
	}

	@Test
	public void testPackageRename1() throws Exception {
		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);

		StringBuffer buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("class A {\n");
		buf.append("}\n");
		ICompilationUnit cu1= fragment.createCompilationUnit("A.java", buf.toString(), true, null);
		setReadOnly(cu1);

		buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("class B {\n");
		buf.append("}\n");
		ICompilationUnit cu2= fragment.createCompilationUnit("B.java", buf.toString(), true, null);
		setReadOnly(cu2);

		RenameJavaElementDescriptor descriptor= RefactoringSignatureDescriptorFactory.createRenameJavaElementDescriptor(IJavaRefactorings.RENAME_PACKAGE);
		descriptor.setJavaElement(fragment);
		descriptor.setNewName("org.test2");
		descriptor.setUpdateReferences(true);
		RefactoringStatus status= performRefactoring(descriptor);
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(2, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(cu1.getPath()));
		assertTrue(validatedEditPaths.contains(cu2.getPath()));
	}

	@Test
	public void testPackageRename2() throws Exception {
		// A readonly and moved, B moved, C changes

		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);

		StringBuffer buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class A {\n");
		buf.append("}\n");
		ICompilationUnit cu1= fragment.createCompilationUnit("A.java", buf.toString(), true, null);
		setReadOnly(cu1);

		buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class B {\n");
		buf.append("}\n");
		fragment.createCompilationUnit("B.java", buf.toString(), true, null);
		// not read only

		IPackageFragment fragment2= getRoot().createPackageFragment("org.other", true, null);

		buf= new StringBuffer();
		buf.append("package org.other;\n");
		buf.append("public class C extends org.test.A {\n");
		buf.append("}\n");
		ICompilationUnit cu3= fragment2.createCompilationUnit("C.java", buf.toString(), true, null);
		setReadOnly(cu3);

		RenameJavaElementDescriptor descriptor= RefactoringSignatureDescriptorFactory.createRenameJavaElementDescriptor(IJavaRefactorings.RENAME_PACKAGE);
		descriptor.setJavaElement(fragment);
		descriptor.setNewName("org.test2");
		descriptor.setUpdateReferences(true);
		RefactoringStatus status= performRefactoring(descriptor);
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(2, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(cu1.getPath()));
		assertTrue(validatedEditPaths.contains(cu3.getPath()));
	}

	@Test
	public void testPackageRenameWithResource() throws Exception {
		// MyClass readonly and moved, x.properties readonly moved

		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);

		StringBuilder buf= new StringBuilder();
		buf.append("package org.test;\n");
		buf.append("public class MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu1= fragment.createCompilationUnit("MyClass.java", buf.toString(), true, null);
		setReadOnly(cu1);

		IFile file= ((IFolder) fragment.getResource()).getFile("x.properties");
		String content= "A file with no references";
		file.create(getStream(content), true, null);
		setReadOnly(file);

		RenameJavaElementDescriptor descriptor= RefactoringSignatureDescriptorFactory.createRenameJavaElementDescriptor(IJavaRefactorings.RENAME_PACKAGE);
		descriptor.setJavaElement(fragment);
		descriptor.setNewName("org.test2");
		descriptor.setUpdateReferences(true);
		RefactoringStatus status= performRefactoring(descriptor);
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(1, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(cu1.getPath()));
	}


	@Test
	public void testPackageRenameWithResource2() throws Exception {
		// MyClass readonly and moved, x.properties readonly moved

		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);

		StringBuilder buf= new StringBuilder();
		buf.append("package org.test;\n");
		buf.append("public class MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu1= fragment.createCompilationUnit("MyClass.java", buf.toString(), true, null);
		setReadOnly(cu1);

		IFile file= ((IFolder) fragment.getResource()).getFile("x.properties");
		byte[] content= "This is about 'org.test' and more".getBytes();
		file.create(new ByteArrayInputStream(content), true, null);
		file.refreshLocal( IResource.DEPTH_ONE, null);
		setReadOnly(file);

		RenameJavaElementDescriptor descriptor= RefactoringSignatureDescriptorFactory.createRenameJavaElementDescriptor(IJavaRefactorings.RENAME_PACKAGE);
		descriptor.setJavaElement(fragment);
		descriptor.setNewName("org.test2");
		descriptor.setUpdateReferences(true);
		descriptor.setUpdateQualifiedNames(true);
		descriptor.setFileNamePatterns("*.properties");
		RefactoringStatus status= performRefactoring(descriptor);
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(2, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(cu1.getPath()));
		assertTrue(validatedEditPaths.contains(file.getFullPath()));
	}

	@Test
	public void testCURename() throws Exception {

		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);

		StringBuffer buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu1= fragment.createCompilationUnit("MyClass.java", buf.toString(), true, null);
		setReadOnly(cu1);

		buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class C extends MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu2= fragment.createCompilationUnit("C.java", buf.toString(), true, null);
		setReadOnly(cu2);

		RenameJavaElementDescriptor descriptor= RefactoringSignatureDescriptorFactory.createRenameJavaElementDescriptor(IJavaRefactorings.RENAME_COMPILATION_UNIT);
		descriptor.setJavaElement(cu1);
		descriptor.setNewName("MyClass2.java");
		descriptor.setUpdateReferences(true);
		RefactoringStatus status= performRefactoring(descriptor);
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(2, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(cu1.getPath()));
		assertTrue(validatedEditPaths.contains(cu2.getPath()));
	}

	@Test
	public void testTypeRename() throws Exception {

		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);

		StringBuffer buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu1= fragment.createCompilationUnit("MyClass.java", buf.toString(), true, null);
		setReadOnly(cu1);

		buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class C extends MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu2= fragment.createCompilationUnit("C.java", buf.toString(), true, null);
		setReadOnly(cu2);

		RenameJavaElementDescriptor descriptor= RefactoringSignatureDescriptorFactory.createRenameJavaElementDescriptor(IJavaRefactorings.RENAME_TYPE);
		descriptor.setJavaElement(cu1.findPrimaryType());
		descriptor.setNewName("MyClass2");
		descriptor.setUpdateReferences(true);
		RefactoringStatus status= performRefactoring(descriptor);
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(2, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(cu1.getPath()));
		assertTrue(validatedEditPaths.contains(cu2.getPath()));
	}

	@Test
	public void testMoveCU2() throws Exception {
		// Move CU and file: Only CU be validated as file doesn't change

		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);
		IPackageFragment otherFragment= getRoot().createPackageFragment("org.test1", true, null);

		StringBuffer buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu1= fragment.createCompilationUnit("MyClass.java", buf.toString(), true, null);
		setReadOnly(cu1);

		IFile file= ((IFolder) fragment.getResource()).getFile("x.properties");
		String content= "A file with no references";
		file.create(getStream(content), true, null);
		setReadOnly(file);

		buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class C extends MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu2= fragment.createCompilationUnit("C.java", buf.toString(), true, null);
		setReadOnly(cu2);

		IMovePolicy policy= ReorgPolicyFactory.createMovePolicy(new IResource[] { file } , new IJavaElement[] { cu1 });
		assertTrue(policy.canEnable());

		JavaMoveProcessor javaMoveProcessor= new JavaMoveProcessor(policy);
		javaMoveProcessor.setDestination(ReorgDestinationFactory.createDestination(otherFragment));
		javaMoveProcessor.setReorgQueries(new MockReorgQueries());
		RefactoringStatus status= performRefactoring(new MoveRefactoring(javaMoveProcessor));
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(2, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(cu1.getPath())); // moved and changed
		assertTrue(validatedEditPaths.contains(cu2.getPath())); // changed
	}

	@Test
	public void testMoveFileWithReplace() throws Exception {
		// Move file to a existing location

		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);
		IPackageFragment otherFragment= getRoot().createPackageFragment("org.test1", true, null);

		IFile file= ((IFolder) fragment.getResource()).getFile("x.properties");
		String content= "A file with no references";
		file.create(getStream(content), true, null);
		setReadOnly(file);

		IFile file2= ((IFolder) otherFragment.getResource()).getFile("x.properties");
		file2.create(getStream(content), true, null);
		setReadOnly(file2);


		IMovePolicy policy= ReorgPolicyFactory.createMovePolicy(new IResource[] { file }, new IJavaElement[] {});
		assertTrue(policy.canEnable());

		JavaMoveProcessor javaMoveProcessor= new JavaMoveProcessor(policy);
		javaMoveProcessor.setDestination(ReorgDestinationFactory.createDestination(otherFragment));
		javaMoveProcessor.setReorgQueries(new MockReorgQueries());
		RefactoringStatus status= performRefactoring(new MoveRefactoring(javaMoveProcessor), true);
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(1, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(file2.getFullPath())); // replaced
	}

	@Test
	public void testMoveCuWithReplace() throws Exception {
		// Move CU to an existing location

		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);
		IPackageFragment otherFragment= getRoot().createPackageFragment("org.test1", true, null);

		StringBuffer buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu1= fragment.createCompilationUnit("MyClass.java", buf.toString(), true, null);
		setReadOnly(cu1);


		buf= new StringBuffer();
		buf.append("package org.test1;\n");
		buf.append("public class MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu2= otherFragment.createCompilationUnit("MyClass.java", buf.toString(), true, null);
		setReadOnly(cu2);


		IMovePolicy policy= ReorgPolicyFactory.createMovePolicy(new IResource[0], new IJavaElement[] { cu1 });
		assertTrue(policy.canEnable());

		JavaMoveProcessor javaMoveProcessor= new JavaMoveProcessor(policy);
		javaMoveProcessor.setDestination(ReorgDestinationFactory.createDestination(otherFragment));
		javaMoveProcessor.setReorgQueries(new MockReorgQueries());
		RefactoringStatus status= performRefactoring(new MoveRefactoring(javaMoveProcessor), false);
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(2, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(cu1.getPath())); // moved and changed
		assertTrue(validatedEditPaths.contains(cu2.getPath())); // replaced
	}

	@Test
	public void testCopyCuWithReplace() throws Exception {
		// Copy CU to a existing location

		IPackageFragment fragment= getRoot().createPackageFragment("org.test", true, null);
		IPackageFragment otherFragment= getRoot().createPackageFragment("org.test1", true, null);

		StringBuffer buf= new StringBuffer();
		buf.append("package org.test;\n");
		buf.append("public class MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu1= fragment.createCompilationUnit("MyClass.java", buf.toString(), true, null);
		setReadOnly(cu1);

		buf= new StringBuffer();
		buf.append("package org.test1;\n");
		buf.append("public class MyClass {\n");
		buf.append("}\n");
		ICompilationUnit cu2= otherFragment.createCompilationUnit("MyClass.java", buf.toString(), true, null);
		setReadOnly(cu2);

		ICopyPolicy policy= ReorgPolicyFactory.createCopyPolicy(new IResource[0], new IJavaElement[] { cu1 });
		assertTrue(policy.canEnable());

		JavaCopyProcessor javaCopyProcessor= new JavaCopyProcessor(policy);
		javaCopyProcessor.setDestination(ReorgDestinationFactory.createDestination(otherFragment));
		javaCopyProcessor.setReorgQueries(new MockReorgQueries());
		javaCopyProcessor.setNewNameQueries(new MockReorgQueries());
		RefactoringStatus status= performRefactoring(new CopyRefactoring(javaCopyProcessor), false);
		if (status != null)
			assertTrue(status.toString(), status.isOK());

		Collection<IPath> validatedEditPaths= RefactoringTestRepositoryProvider.getValidatedEditPaths(getRoot().getJavaProject().getProject());
		assertEquals(1, validatedEditPaths.size());
		assertTrue(validatedEditPaths.contains(cu2.getPath())); // replaced
	}


	private static void setReadOnly(ICompilationUnit cu) throws CoreException {
		setReadOnly(cu.getResource());
	}


	private static void setReadOnly(IResource resource) throws CoreException {
		ResourceAttributes resourceAttributes = resource.getResourceAttributes();
		if (resourceAttributes != null) {
			resourceAttributes.setReadOnly(true);
			resource.setResourceAttributes(resourceAttributes);
		}
	}

}
