/*******************************************************************************
 * Copyright (c) 2006, 2015 Wind River Systems, Inc. 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:
 *     Anton Leherbauer (Wind River Systems) - initial API and implementation
 *     Andrew Eidsness - fix and test for bug 278632
 *     Serge Beauchamp (Freescale Semiconductor) - Bug 417909
 *******************************************************************************/
package org.eclipse.cdt.ui.tests.text;

import java.io.File;
import java.lang.ref.WeakReference;
import java.net.URI;
import java.net.URISyntaxException;

import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CModelException;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.ResourceHelper;
import org.eclipse.cdt.internal.core.model.ExternalTranslationUnit;
import org.eclipse.cdt.internal.ui.editor.CEditor;
import org.eclipse.cdt.internal.ui.editor.CEditorMessages;
import org.eclipse.cdt.internal.ui.util.EditorUtility;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.testplugin.Accessor;
import org.eclipse.cdt.ui.testplugin.DisplayHelper;
import org.eclipse.cdt.ui.testplugin.EditorTestHelper;
import org.eclipse.cdt.ui.testplugin.FileTool;
import org.eclipse.cdt.ui.testplugin.ResourceTestHelper;
import org.eclipse.cdt.ui.tests.BaseUITestCase;
import org.eclipse.cdt.ui.text.ICColorConstants;
import org.eclipse.cdt.ui.text.IColorManager;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.filesystem.provider.FileSystem;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;

import junit.framework.Test;
import junit.framework.TestSuite;

/**
 * Basic CEditor tests.
 *
 * @since 4.0
 */
public class BasicCEditorTest extends BaseUITestCase {

	final static class TestDocListener implements IDocumentListener {
		public boolean fDocChanged;

		@Override
		public void documentAboutToBeChanged(DocumentEvent event) {
		}

		@Override
		public void documentChanged(DocumentEvent event) {
			fDocChanged = true;
		}
	}

	public static class Bug278632FileSystem extends FileSystem {
		@Override
		public IFileStore getStore(URI uri) {
			try {
				// For the test case, this just returns the FS implementation used for the null
				// filesystem. In a real application this would be a real implementation,
				// however for the purposes of exposing the bug, any non-"file://" scheme will do.
				return EFS.getStore(new URI(EFS.getNullFileSystem().getScheme(), uri.getSchemeSpecificPart(), null));
			} catch (URISyntaxException | CoreException e) {
				throw new RuntimeException(e);
			}
		}
	}

	private CEditor fEditor;
	private SourceViewer fSourceViewer;
	private ICProject fCProject;
	private IProject fNonCProject;
	private StyledText fTextWidget;
	private Accessor fAccessor;
	private IDocument fDocument;
	private TestDocListener fDocListener = new TestDocListener();

	public static Test suite() {
		return new TestSuite(BasicCEditorTest.class);
	}

	@Override
	protected void setUp() throws Exception {
		closeWelcome();
		super.setUp();
	}

	@Override
	protected void tearDown() throws Exception {
		EditorTestHelper.closeEditor(fEditor);
		if (fCProject != null)
			CProjectHelper.delete(fCProject);
		if (fNonCProject != null) {
			ResourceHelper.delete(fNonCProject);
		}
		super.tearDown();
	}

	private void setUpEditor(IFile file) throws PartInitException {
		IEditorPart editor = EditorTestHelper.openInEditor(file, true);
		assertNotNull(editor);
		assertTrue(editor instanceof CEditor);
		fEditor = (CEditor) editor;
		fTextWidget = fEditor.getViewer().getTextWidget();
		assertNotNull(fTextWidget);
		fAccessor = new Accessor(fTextWidget, StyledText.class);
		fDocument = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
		assertNotNull(fDocument);
	}

	private void setUpEditor(String file) throws PartInitException {
		setUpEditor(ResourceTestHelper.findFile(file));
	}

	private void setUpEditor(File file) throws PartInitException, CModelException {
		IEditorPart editor = EditorUtility
				.openInEditor(new ExternalTranslationUnit(fCProject, file.toURI(), CCorePlugin.CONTENT_TYPE_CXXSOURCE));
		assertNotNull(editor);
		assertTrue(editor instanceof CEditor);
		fEditor = (CEditor) editor;
		fTextWidget = fEditor.getViewer().getTextWidget();
		assertNotNull(fTextWidget);
		fAccessor = new Accessor(fTextWidget, StyledText.class);
		fDocument = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
		assertNotNull(fDocument);
	}

	private void setUpEditorUsingFileStore(File file) throws CoreException {
		final IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
		IEditorPart editor = IDE.openEditorOnFileStore(activePage, EFS.getStore(URIUtil.toURI(file.getAbsolutePath())));
		assertNotNull(editor);
		assertTrue(editor instanceof CEditor);
		fEditor = (CEditor) editor;
		fTextWidget = fEditor.getViewer().getTextWidget();
		assertNotNull(fTextWidget);
		fAccessor = new Accessor(fTextWidget, StyledText.class);
		fDocument = fEditor.getDocumentProvider().getDocument(fEditor.getEditorInput());
		assertNotNull(fDocument);
	}

	public void testEditTranslationUnit() throws Exception {
		final String file = "/ceditor/src/main.cpp";
		fCProject = EditorTestHelper.createCProject("ceditor", "resources/ceditor", false, false);
		IFile mainFile = ResourceTestHelper.findFile(file);
		assertNotNull(mainFile);
		setUpEditor(mainFile);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		String content = fDocument.get();
		setCaret(0);
		String newtext = "/* " + getName() + " */";
		type(newtext);
		type('\n');
		String newContent = fDocument.get();
		assertEquals("Edit failed", newtext, newContent.substring(0, newtext.length()));
		// save
		fEditor.doSave(new NullProgressMonitor());
		assertFalse("Editor is still dirty", fEditor.isDirty());
		// close and reopen
		EditorTestHelper.closeEditor(fEditor);
		setUpEditor(mainFile);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		content = fDocument.get();
		assertEquals("Save failed", newContent, content);
		// check reconciler
		ITranslationUnit tUnit = fEditor.getInputCElement();
		ICElement[] children = tUnit.getChildren();
		assertEquals(2, children.length);
		setCaret(content.length());
		type('\n');
		type("void func() {}\n");
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		children = tUnit.getChildren();
		assertEquals(3, children.length);
	}

	//{Point.cpp}
	//#include <math.h>
	//class Point {
	//public:
	//	Point(double xc, double yc) :
	//		x(xc), y(yc) {}
	//	double distance(const Point& other) const;
	//	int compareX(const Point& other) const;
	//	double x;
	//	double y;
	//};
	//double Point::distance(const Point& other) const {
	//	double dx = x - other.x;
	//	double dy = y - other.y;
	//	return sqrt(dx * dx + dy * dy);
	//}
	//int Point::compareX(const Point& other) const {
	//	if (x < other.x) {
	//		return -1;
	//	}
	//	else if (x > other.x) {
	//		return 1;
	//	}
	//	else {
	//		return 0;
	//	}
	//}
	//
	public void testEditNewTranslationUnit() throws Exception {
		fCProject = EditorTestHelper.createCProject("ceditor", "resources/ceditor", false, false);
		IFile newFile = createFile(fCProject.getProject(), "Point.cpp", "");
		assertNotNull(newFile);
		setUpEditor(newFile);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		String content = fDocument.get();
		setCaret(0);
		String newText = "/* " + getName() + " */\n";
		newText += readTaggedComment("Point.cpp");
		String[] lines = newText.split("\\r\\n|\\r|\\n");
		for (int i = 0; i < lines.length; i++) {
			String line = lines[i].trim();
			if (line.startsWith("}")) {
				setCaret(fDocument.get().indexOf(line, getCaret()) + line.length());
				Thread.sleep(100);
			} else {
				if (i > 0)
					type('\n');
				type(line);
				Thread.sleep(50);
			}
		}
		String newContent = fDocument.get();
		String[] newLines = newContent.split("\\r\\n|\\r|\\n");
		for (int i = 0; i < lines.length; i++) {
			String line = lines[i];
			assertEquals(line, newLines[i]);
		}
		// save
		fEditor.doSave(new NullProgressMonitor());
		assertFalse("Editor is still dirty", fEditor.isDirty());
		// close and reopen
		EditorTestHelper.closeEditor(fEditor);
		setUpEditor(newFile);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		content = fDocument.get().trim();
		assertEquals("Save failed", newContent, content);
		// check reconciler
		ITranslationUnit tUnit = fEditor.getInputCElement();
		ICElement[] children = tUnit.getChildren();
		assertEquals(4, children.length);
		setCaret(content.length());
		type('\n');
		type("void func() {}\n");
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		children = tUnit.getChildren();
		assertEquals(5, children.length);
	}

	public void testEditInNonCProject() throws Exception {
		final String file = "/ceditor/src/main.cpp";
		fNonCProject = EditorTestHelper.createNonCProject("ceditor", "resources/ceditor", false);
		setUpEditor(file);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		String content = fDocument.get();
		setCaret(0);
		String newtext = "/* " + getName() + " */";
		type(newtext);
		type('\n');
		String newContent = fDocument.get();
		assertEquals("Edit failed", newtext, newContent.substring(0, newtext.length()));
		// save
		fEditor.doSave(new NullProgressMonitor());
		assertFalse("Editor is still dirty", fEditor.isDirty());
		// close and reopen
		EditorTestHelper.closeEditor(fEditor);
		setUpEditor(file);
		content = fDocument.get();
		assertEquals("Save failed", newContent, content);
	}

	public void testEditExternalTranslationUnit() throws Exception {
		final String file = "/ceditor/src/main.cpp";
		fCProject = EditorTestHelper.createCProject("ceditor", "resources/ceditor", false, false);
		IFile mainFile = ResourceTestHelper.findFile(file);
		assertNotNull(mainFile);
		File tmpFile = File.createTempFile("tmp", ".cpp");
		tmpFile.deleteOnExit();
		FileTool.copy(mainFile.getLocation().toFile(), tmpFile);
		setUpEditor(tmpFile);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		String content = fDocument.get();
		setCaret(0);
		String newtext = "/* " + getName() + " */";
		type(newtext);
		type('\n');
		String newContent = fDocument.get();
		assertEquals("Edit failed", newtext, newContent.substring(0, newtext.length()));
		// save
		fEditor.doSave(new NullProgressMonitor());
		assertFalse("Editor is still dirty", fEditor.isDirty());
		// close and reopen
		EditorTestHelper.closeEditor(fEditor);
		setUpEditor(tmpFile);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		content = fDocument.get();
		assertEquals("Save failed", newContent, content);
		// check reconciler
		ITranslationUnit tUnit = fEditor.getInputCElement();
		ICElement[] children = tUnit.getChildren();
		assertEquals(2, children.length);
		setCaret(content.length());
		type('\n');
		type("void func() {}\n");
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		children = tUnit.getChildren();
		assertEquals(3, children.length);
		tmpFile.delete();
	}

	public void testEditExternalTranslationUnitUsingFileStore() throws Exception {
		final String file = "/ceditor/src/main.cpp";
		fCProject = EditorTestHelper.createCProject("ceditor", "resources/ceditor", false, false);
		IFile mainFile = ResourceTestHelper.findFile(file);
		assertNotNull(mainFile);
		File tmpFile = File.createTempFile("tmp", ".cpp");
		tmpFile.deleteOnExit();
		FileTool.copy(mainFile.getLocation().toFile(), tmpFile);
		setUpEditorUsingFileStore(tmpFile);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		String content = fDocument.get();
		setCaret(0);
		String newtext = "/* " + getName() + " */";
		type(newtext);
		type('\n');
		String newContent = fDocument.get();
		assertEquals("Edit failed", newtext, newContent.substring(0, newtext.length()));
		// save
		fEditor.doSave(new NullProgressMonitor());
		assertFalse("Editor is still dirty", fEditor.isDirty());
		// close and reopen
		EditorTestHelper.closeEditor(fEditor);
		setUpEditor(tmpFile);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		content = fDocument.get();
		assertEquals("Save failed", newContent, content);
		// check reconciler
		ITranslationUnit tUnit = fEditor.getInputCElement();
		ICElement[] children = tUnit.getChildren();
		assertEquals(2, children.length);
		setCaret(content.length());
		type('\n');
		type("void func() {}\n");
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		children = tUnit.getChildren();
		assertEquals(3, children.length);
		tmpFile.delete();
	}

	public void testSyntaxHighlighting_Bug180433() throws Exception {
		IColorManager colorMgr = CUIPlugin.getDefault().getTextTools().getColorManager();
		colorMgr.unbindColor(ICColorConstants.PP_DIRECTIVE);
		colorMgr.bindColor(ICColorConstants.PP_DIRECTIVE, new RGB(7, 7, 7));
		final Color ppDirectiveColor = colorMgr.getColor(ICColorConstants.PP_DIRECTIVE);
		final String file = "/ceditor/src/main.cpp";
		fCProject = EditorTestHelper.createCProject("ceditor", "resources/ceditor", false, false);
		setUpEditor(file);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		String content = fDocument.get();
		String include = "#include";
		int includeIdx = content.indexOf(include);
		StyleRange style = fTextWidget.getStyleRangeAtOffset(includeIdx);
		assertSame(style.foreground, ppDirectiveColor);
	}

	public void testNonFileEFSResource_Bug278632() {
		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
		assertNotNull(page);

		IEditorRegistry reg = page.getWorkbenchWindow().getWorkbench().getEditorRegistry();
		String editorID = reg.getDefaultEditor(".c").getId();

		URI uri = null;
		try {
			uri = new URI("bug278632", "/folder/file", null);
		} catch (URISyntaxException e) {
			e.printStackTrace();
		}
		assertNotNull(uri);

		IEditorPart part = null;
		try {
			part = IDE.openEditor(page, uri, editorID, true);
		} catch (PartInitException e) {
			e.printStackTrace();
		}
		assertNotNull(part);
		assertTrue(part instanceof CEditor);
	}

	public static void closeWelcome() {
		try {
			IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
			IWorkbenchPage activePage = window.getActivePage();
			IWorkbenchPart activePart = activePage.getActivePart();
			if (activePart.getTitle().equals("Welcome")) {
				activePart.dispose();
			}
		} catch (Exception e) {
			// ignore
		}
	}

	public void testLeakingInstanceAfterClose() throws Exception {
		final String file = "/ceditor/src/main.cpp";
		fCProject = EditorTestHelper.createCProject("ceditor", "resources/ceditor", false, false);
		setUpEditor(file);
		fSourceViewer = EditorTestHelper.getSourceViewer(fEditor);
		assertTrue(EditorTestHelper.joinReconciler(fSourceViewer, 0, 10000, 100));
		WeakReference<CEditor> ref = new WeakReference<>(fEditor);
		EditorTestHelper.closeEditor(fEditor);
		fEditor = null;
		fSourceViewer = null;
		int ngc = 0;
		while (ref.get() != null && ngc++ < 100) {
			System.gc();
			EditorTestHelper.runEventQueue(200);
		}
		System.out
				.println("BasicCEditorTest.testLeakingInstanceAfterClose took " + ngc + " iterations of loop to exit");
		assertNull("CEditor instance seems to be leaking after close", ref.get());
	}

	/**
	 * Type characters into the styled text.
	 *
	 * @param characters the characters to type
	 */
	private void type(CharSequence characters) {
		for (int i = 0; i < characters.length(); i++)
			type(characters.charAt(i), 0, 0);
	}

	/**
	 * Type a character into the styled text.
	 *
	 * @param character the character to type
	 */
	private void type(char character) {
		type(character, 0, 0);
	}

	/**
	 * Type a character into the styled text.
	 *
	 * @param character the character to type
	 * @param keyCode the key code
	 * @param stateMask the state mask
	 */
	private void type(char character, int keyCode, int stateMask) {
		fDocument.addDocumentListener(fDocListener);
		fDocListener.fDocChanged = false;
		Event event = new Event();
		event.character = character;
		event.keyCode = keyCode;
		event.stateMask = stateMask;
		fAccessor.invoke("handleKeyDown", new Object[] { event });

		new DisplayHelper() {
			@Override
			protected boolean condition() {
				return fDocListener.fDocChanged;
			}
		}.waitForCondition(EditorTestHelper.getActiveDisplay(), 50);
		fDocument.removeDocumentListener(fDocListener);
	}

	private int getCaret() {
		return ((ITextSelection) fEditor.getSelectionProvider().getSelection()).getOffset();
	}

	private void setCaret(int offset) {
		fEditor.getSelectionProvider().setSelection(new TextSelection(offset, 0));
		int newOffset = ((ITextSelection) fEditor.getSelectionProvider().getSelection()).getOffset();
		assertEquals(offset, newOffset);
	}

	// See Bug 417909 - Opening a large file from a progress dialog causes the scalability dialog to
	// disappear.
	public void testScalabilityDialogNotDismissedInadvertently_417909() throws Exception {
		// 1. Create a project with a very large source file.
		fCProject = EditorTestHelper.createCProject("ceditor", "resources/ceditor", false, false);

		// 1a. Dynamically create the large source file.
		String originalFile = "/ceditor/src/main.cpp";
		String file = "/ceditor/src/large_main.cpp";
		ResourceTestHelper.copy(originalFile, file);

		setUpEditor(file);

		StringBuilder buffer = new StringBuilder(fDocument.get());

		buffer.append("unsigned long c[250000] = {\n");
		for (int i = 0; i < 12499; i++)
			buffer.append("	0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,\n");
		buffer.append("	0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1,0x0,0x1\n};\n");

		fDocument.set(buffer.toString());
		fEditor.doSave(new NullProgressMonitor());
		EditorTestHelper.closeEditor(fEditor);

		// 2. Create and open a progress dialog window.
		IWorkbenchWindow window = EditorTestHelper.getActiveWorkbenchWindow();
		ProgressMonitorDialog dialog = new ProgressMonitorDialog(window.getShell());
		dialog.open();

		// 3. Open the large source file in the editor, which should cause the
		// scalability dialog to be displayed.
		setUpEditor(file);

		// 4. Close the progress dialog window
		dialog.close();

		// 5. Verify that the scalability dialog has not been closed
		// unexpectedly.
		Shell scalabilityDialog = null;
		Shell[] shells = Display.getCurrent().getShells();
		for (Shell shell : shells) {
			if (shell.getText().equals(CEditorMessages.Scalability_info)) {
				scalabilityDialog = shell;
				break;
			}
		}

		assertNotNull(scalabilityDialog);
		scalabilityDialog.close();
		EditorTestHelper.closeEditor(fEditor);
	}
}
