package org.eclipse.tm4e.ui;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.tests.harness.util.DisplayHelper;
import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;

public class TMinGenericEditorTest {
	
	private IEditorDescriptor editorDescriptor;
	private File f;
	private IEditorPart editor;

	private Collection<Thread> getTM4EThreads() {
		Set<Thread> threads = Thread.getAllStackTraces().keySet();
		Set<Thread> res = new HashSet<>();
		for (Thread thread : threads) {
			if (thread.getClass().getName().contains("tm4e")) {
				res.add(thread);
			}
		}
		return res;
	}
	
	@Before
	public void checkHasGenericEditor() {
		editorDescriptor = PlatformUI.getWorkbench().getEditorRegistry().findEditor("org.eclipse.ui.genericeditor.GenericEditor");
		Assume.assumeNotNull(editorDescriptor);
		Assert.assertTrue("TM4E threads still running", getTM4EThreads().isEmpty());
	}
	
	@After
	public void tearDown() {
		editor.getEditorSite().getPage().closeEditor(editor, false);
		editor = null;
		f.delete();
		f = null;
	}

	@Test
	public void testTMHighlightInGenericEditor() throws IOException, PartInitException {
		f = File.createTempFile("test" + System.currentTimeMillis(), ".ts");
		FileOutputStream fileOutputStream = new FileOutputStream(f);
		fileOutputStream.write("let a = '';\nlet b = 10;\nlet c = true;".getBytes());
		fileOutputStream.close();
		f.deleteOnExit();
		editor = IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(),
				f.toURI(), editorDescriptor.getId(), true);
		StyledText text = (StyledText)editor.getAdapter(Control.class);
		new DisplayHelper() {
			@Override
			protected boolean condition() {
				return text.getStyleRanges().length > 1;
			}
		}.waitForCondition(text.getDisplay(), 3000);
		Assert.assertTrue(text.getStyleRanges().length > 1);
	}

	@Test
	public void testReconcilierStartsAndDisposeThread() throws Exception {
		testTMHighlightInGenericEditor();
		editor.getEditorSite().getPage().closeEditor(editor, false);
		Thread.sleep(500); // give time to dispose
		Assert.assertTrue(getTM4EThreads().isEmpty());
	}

}

@@ -2270,24 +2270,1057 @@
 gth %3E 1);%0A%09%7D
+%0A%09%0A%09@Test%0A%09public void testTMHighlightInGenericEditorEdit() throws IOException, PartInitException %7B%0A%09%09f = File.createTempFile(%22test%22 + System.currentTimeMillis(), %22.ts%22);%0A%09%09FileOutputStream fileOutputStream = new FileOutputStream(f);%0A%09%09fileOutputStream.write(%22let a = '';%22.getBytes());%0A%09%09fileOutputStream.close();%0A%09%09f.deleteOnExit();%0A%09%09editor = IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(),%0A%09%09%09%09f.toURI(), editorDescriptor.getId(), true);%0A%09%09StyledText text = (StyledText)editor.getAdapter(Control.class);%0A%09%09new DisplayHelper() %7B%0A%09%09%09@Override%0A%09%09%09protected boolean condition() %7B%0A%09%09%09%09return text.getStyleRanges().length %3E 1;%0A%09%09%09%7D%0A%09%09%7D.waitForCondition(text.getDisplay(), 3000);%0A%09%09int numberOfRanges = text.getStyleRanges().length;%0A%09%09Assert.assertTrue(numberOfRanges %3E 1);%0A%09%09text.setText(%22let a = '';%5Cnlet b = 10;%5Cnlet c = true;%22);%0A%09%09DisplayHelper.runEventLoop(text.getDisplay(), 3000);%0A%09%09Assert.assertTrue(%22More styles should have been added%22, text.getStyleRanges().length %3E numberOfRanges + 3);%0A%09%7D
 %0A%0A%09@Test%0A%09pu

Test update editor updates style