/*******************************************************************************
 * Copyright (c) 2019 Paul Pazderski 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:
 *     Paul Pazderski - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.tests.console;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.debug.tests.AbstractDebugTest;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.console.TextConsoleViewer;

/**
 * Not really a test for {@link TextConsoleViewer} yet since it only test one
 * private method of it.
 */
public class TextConsoleViewerTest extends AbstractDebugTest {

	public TextConsoleViewerTest() {
		super(TextConsoleViewerTest.class.getSimpleName());
	}

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

	/**
	 * Test override of existing styles with a new style. Typically used to
	 * apply link styling on already styled console document.
	 */
	public void testStyleOverride() throws Throwable {
		Color colorR = null;
		Color colorG = null;
		Color colorB = null;
		Color colorK = null;
		Color colorW = null;
		try {
			final Method method = TextConsoleViewer.class.getDeclaredMethod("overrideStyleRange", List.class, StyleRange.class);
			method.setAccessible(true);
			assertTrue("Required method <" + method + "> is not static.", Modifier.isStatic(method.getModifiers()));

			final List<StyleRange> styles = new ArrayList<>();
			colorR = new Color(null, 255, 0, 0);
			colorG = new Color(null, 0, 255, 0);
			colorB = new Color(null, 0, 0, 255);
			colorK = new Color(null, 0, 0, 0);
			colorW = new Color(null, 255, 255, 255);

			// overwrite in empty list
			method.invoke(null, styles, new StyleRange(5, 5, colorR, null));
			checkOverlapping(styles);
			assertStyle(styles, 2, 5, null);
			assertStyle(styles, 5, 10, colorR);
			assertStyle(styles, 10, 13, null);

			// overwrite unstyled part before
			method.invoke(null, styles, new StyleRange(0, 3, colorG, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 3, colorG);
			assertStyle(styles, 3, 5, null);
			assertStyle(styles, 5, 10, colorR);
			assertStyle(styles, 10, 13, null);

			// overwrite unstyled part after
			method.invoke(null, styles, new StyleRange(15, 5, colorB, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 3, colorG);
			assertStyle(styles, 3, 5, null);
			assertStyle(styles, 5, 10, colorR);
			assertStyle(styles, 10, 15, null);
			assertStyle(styles, 15, 20, colorB);
			assertStyle(styles, 20, 23, null);

			// overwrite existing: start exact, end exact
			method.invoke(null, styles, new StyleRange(0, 3, colorK, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 3, colorK);
			assertStyle(styles, 3, 5, null);
			assertStyle(styles, 5, 10, colorR);
			assertStyle(styles, 10, 15, null);
			assertStyle(styles, 15, 20, colorB);
			assertStyle(styles, 20, 23, null);

			// overwrite existing: start exact, end after
			method.invoke(null, styles, new StyleRange(0, 4, colorW, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 4, colorW);
			assertStyle(styles, 4, 5, null);
			assertStyle(styles, 5, 10, colorR);
			assertStyle(styles, 10, 15, null);
			assertStyle(styles, 15, 20, colorB);
			assertStyle(styles, 20, 23, null);

			// overwrite existing: start exact, end inside
			method.invoke(null, styles, new StyleRange(0, 2, colorK, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 2, colorK);
			assertStyle(styles, 2, 4, colorW);
			assertStyle(styles, 4, 5, null);
			assertStyle(styles, 5, 10, colorR);
			assertStyle(styles, 10, 15, null);
			assertStyle(styles, 15, 20, colorB);
			assertStyle(styles, 20, 23, null);

			// overwrite existing: start before, end exact
			method.invoke(null, styles, new StyleRange(13, 7, colorW, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 2, colorK);
			assertStyle(styles, 2, 4, colorW);
			assertStyle(styles, 4, 5, null);
			assertStyle(styles, 5, 10, colorR);
			assertStyle(styles, 10, 13, null);
			assertStyle(styles, 13, 20, colorW);
			assertStyle(styles, 20, 23, null);

			// overwrite existing: start inside, end exact
			method.invoke(null, styles, new StyleRange(15, 5, colorK, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 2, colorK);
			assertStyle(styles, 2, 4, colorW);
			assertStyle(styles, 4, 5, null);
			assertStyle(styles, 5, 10, colorR);
			assertStyle(styles, 10, 13, null);
			assertStyle(styles, 13, 15, colorW);
			assertStyle(styles, 15, 20, colorK);
			assertStyle(styles, 20, 23, null);

			// prepare new existing style
			styles.clear();
			method.invoke(null, styles, new StyleRange(10, 10, colorW, null));
			assertStyle(styles, 10, 20, colorW);
			method.invoke(null, styles, new StyleRange(10, 10, colorK, null));
			assertStyle(styles, 10, 20, colorK);
			assertEquals("Wrong number of styles.", 1, styles.size());

			// overwrite existing: start before, end after
			method.invoke(null, styles, new StyleRange(5, 15, colorR, null));
			checkOverlapping(styles);
			assertStyle(styles, 5, 20, colorR);

			// overwrite existing: start before, end inside
			method.invoke(null, styles, new StyleRange(0, 10, colorG, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 10, colorG);
			assertStyle(styles, 10, 20, colorR);

			// overwrite existing: start inside, end after
			method.invoke(null, styles, new StyleRange(15, 10, colorB, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 10, colorG);
			assertStyle(styles, 10, 15, colorR);
			assertStyle(styles, 15, 20, colorB);

			// overwrite existing: start inside, end inside
			method.invoke(null, styles, new StyleRange(6, 1, colorW, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 6, colorG);
			assertStyle(styles, 6, 7, colorW);
			assertStyle(styles, 7, 10, colorG);
			assertStyle(styles, 10, 15, colorR);
			assertStyle(styles, 15, 20, colorB);

			// overwrite many styles
			method.invoke(null, styles, new StyleRange(0, 25, colorK, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 25, colorK);
			assertStyle(styles, 25, 30, null);

			// prepare new existing style
			styles.clear();
			styles.add(new StyleRange(0, 10, colorR, null));
			styles.add(new StyleRange(15, 5, colorG, null));

			// overwrite: start in one style, end in other
			method.invoke(null, styles, new StyleRange(7, 11, colorB, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 7, colorR);
			assertStyle(styles, 7, 18, colorB);
			assertStyle(styles, 18, 20, colorG);
			assertStyle(styles, 20, 25, null);

			// prepare new existing style
			styles.clear();
			styles.add(new StyleRange(0, 10, colorR, null));
			styles.add(new StyleRange(15, 5, colorG, null));

			// overwrite: start in one style, end after other
			method.invoke(null, styles, new StyleRange(7, 15, colorB, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 7, colorR);
			assertStyle(styles, 7, 22, colorB);
			assertStyle(styles, 22, 25, null);

			// prepare new existing style
			styles.clear();
			styles.add(new StyleRange(5, 5, colorR, null));
			styles.add(new StyleRange(15, 5, colorG, null));

			// overwrite: start before one style, end in other
			method.invoke(null, styles, new StyleRange(2, 15, colorB, null));
			checkOverlapping(styles);
			assertStyle(styles, 0, 2, null);
			assertStyle(styles, 2, 17, colorB);
			assertStyle(styles, 17, 20, colorG);
			assertStyle(styles, 20, 25, null);

		} catch (InvocationTargetException e) {
			if (e.getTargetException() != null) {
				throw e.getTargetException();
			}
			throw e;
		} catch (Exception e) {
			// if this happened the method may have be renamed or moved
			throw e;
		}
		finally {
			if (colorR != null) {
				colorR.dispose();
			}
			if (colorG != null) {
				colorG.dispose();
			}
			if (colorB != null) {
				colorB.dispose();
			}
			if (colorK != null) {
				colorK.dispose();
			}
			if (colorW != null) {
				colorW.dispose();
			}
		}
	}

	/**
	 * Assert any offset in given range is styled with given foreground color.
	 * <p>
	 * Note: this test class only uses foreground color and assumes all other
	 * style attributes are set to there default values.
	 * </p>
	 *
	 * @param styles list of known style ranges
	 * @param offset inclusive start offset of range to check
	 * @param end exclusive end offset of range to check
	 * @param foregroundColor the expected foreground color for styles in given
	 *            range. May be <code>null</code> to check for unstyled ranges.
	 */
	private static void assertStyle(List<StyleRange> styles, int offset, int end, Color foregroundColor) {
		int o = offset;
		while (o < end) {
			final StyleRange expected = foregroundColor != null ? new StyleRange(0, 0, foregroundColor, null) : null;
			final StyleRange actual = getStyleAtOffset(styles, o);
			assertEquals("Got wrong style at offset " + o, generalizeStyle(expected), generalizeStyle(actual));
			final int step = actual != null ? actual.length : 1;
			o += Math.min(step, 1);
		}
	}

	/**
	 * Get style from list at given offset or <code>null</code>. If offset has
	 * more then one style it is undefined which one is returned. Does not
	 * return zero-length styles.
	 *
	 * @param styles list of styles
	 * @param offset offset of interest
	 * @return style at given offset or <code>null</code> if offset is not
	 *         styled
	 */
	private static StyleRange getStyleAtOffset(List<StyleRange> styles, int offset) {
		if (styles != null) {
			for (StyleRange style : styles) {
				if (style.start <= offset && style.start + style.length >= offset + 1) {
					return style;
				}
			}
		}
		return null;
	}

	/**
	 * Set styles start and length to <code>0</code> to compare only the styling
	 * parts using <code>equals</code>.
	 *
	 * @param style the original style. Not modified by this method.
	 * @return the style without position information.
	 */
	private static StyleRange generalizeStyle(StyleRange style) {
		if (style == null) {
			return new StyleRange();
		}
		final StyleRange copy = (StyleRange) style.clone();
		copy.start = copy.length = 0;
		return copy;
	}

	/**
	 * Check if styles are disjoint and sorted ascending by offset.
	 *
	 * @param styles the styles to check
	 */
	private static void checkOverlapping(List<StyleRange> styles) {
		if (styles == null || styles.size() <= 1) {
			return;
		}
		int lastEnd = Integer.MIN_VALUE;
		for (StyleRange s : styles) {
			assertTrue("Styles overlap or not sorted.", lastEnd <= s.start);
			assertTrue("Empty style.", s.length > 0);
			lastEnd = s.start + s.length;
		}
	}
}
