/*******************************************************************************
 * Copyright (c) 2000, 2013 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.jface.text.tests.rules;

import static org.junit.Assert.assertEquals;

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

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.rules.FastPartitioner;
import org.eclipse.jface.text.rules.IPartitionTokenScanner;
import org.eclipse.jface.text.rules.IPredicateRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.MultiLineRule;
import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;
import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;


/**
 * @since 3.0
 */
public class FastPartitionerTest {

	protected static final String COMMENT= "comment";
	protected static final String DEFAULT= IDocument.DEFAULT_CONTENT_TYPE;

	private IDocument fDoc;
	private IDocumentPartitioner fPartitioner;

	@Before
	public void setUp() {
		fDoc= new Document();
		IPartitionTokenScanner scanner= new RuleBasedPartitionScanner() {
			{
				IToken comment= new Token(COMMENT);
				IPredicateRule[] rules= new IPredicateRule[] { new MultiLineRule("/*", "*/", comment) };
				setPredicateRules(rules);

			}
		};
		fPartitioner= createPartitioner(scanner);
		fDoc.setDocumentPartitioner(fPartitioner);
		fPartitioner.connect(fDoc);
	}

	protected IDocumentPartitioner createPartitioner(IPartitionTokenScanner scanner) {
		return new FastPartitioner(scanner, new String[] { DEFAULT, COMMENT });
	}

	@Test
	public void testGetPartition() {
		fDoc.set("docu     ment/* comment */docu     ment");

		int[] offsets= new int[] { 13, 26 };
		assertGetPartition_InterleavingPartitions(offsets);
	}

	@Test
	public void testGetPartitionEmptyMiddle() {
		fDoc.set("docu     ment/* comment *//* comment */docu     ment");

		int[] offsets= new int[] { 13, 26, 26, 39 };
		assertGetPartition_InterleavingPartitions(offsets);
	}
	
	@Test
	public void testGetPartitionEmptyStart() {
		fDoc.set("/* comment */docu     ment");

		int[] offsets= new int[] { 0, 13 };
		assertGetPartition_InterleavingPartitions(offsets);
	}

	@Test
	public void testGetPartitionEmptyEnd() {
		fDoc.set("docu     ment/* comment */");

		int[] offsets= new int[] { 13, 26 };
		assertGetPartition_InterleavingPartitions(offsets);
	}

	@Test
	public void testGetContentType() {
		fDoc.set("docu     ment/* comment */docu     ment");

		int[] offsets= new int[] { 13, 26 };
		assertGetContentType_InterleavingPartitions(offsets);
	}

	@Test
	public void testGetContentTypeEmptyMiddle() {
		fDoc.set("docu     ment/* comment *//* comment */docu     ment");

		int[] offsets= new int[] { 13, 26, 26, 39 };
		assertGetContentType_InterleavingPartitions(offsets);
	}

	@Test
	public void testGetContentTypeEmptyStart() {
		fDoc.set("/* comment */docu     ment");

		int[] offsets= new int[] { 0, 13 };
		assertGetContentType_InterleavingPartitions(offsets);
	}

	@Test
	public void testGetContentTypeEmptyEnd() {
		fDoc.set("docu     ment/* comment */");

		int[] offsets= new int[] { 13, 26 };
		assertGetContentType_InterleavingPartitions(offsets);
	}

	@Test
	public void testComputePartitioning() {
		fDoc.set("docu     ment/* comment */docu     ment");

		int[] offsets= new int[] { 13, 26 };
		assertComputePartitioning_InterleavingPartitions(offsets);
	}

	@Test
	public void testComputePartitioningEmptyMiddle() {
		fDoc.set("docu     ment/* comment *//* comment */docu     ment");

		int[] offsets= new int[] { 13, 26, 26, 39 };
		assertComputePartitioning_InterleavingPartitions(offsets);
	}

	@Test
	public void testComputePartitioningEmptyStart() {
		fDoc.set("/* comment */docu     ment");

		int[] offsets= new int[] { 0, 13 };
		assertComputePartitioning_InterleavingPartitions(offsets);
	}

	@Test
	public void testComputePartitioningEmptyEnd() {
		fDoc.set("docu     ment/* comment */");

		int[] offsets= new int[] { 13, 26 };
		assertComputePartitioning_InterleavingPartitions(offsets);
	}

	@Test
	public void testComputePartitioningSubrangeBeforeBoundaries() {
		fDoc.set("docu     ment/* comment *//* comment */docu     ment");

		int[] offsets= new int[] { 13, 26, 26 };
		assertComputePartitioning_InterleavingPartitions(12, 38, offsets, DEFAULT);
	}

	@Test
	public void testComputePartitioningSubrangeOnBoundaries() {
		fDoc.set("docu     ment/* comment *//* comment */docu     ment");

		int[] offsets= new int[] { 13, 26, 26, 39 };
		assertComputePartitioning_InterleavingPartitions(13, 39, offsets, DEFAULT);
	}

	@Test
	public void testComputePartitioningSubrangeOnBoundaries2() {
		fDoc.set("/* comment *//* comment *//* comment */");

		int[] offsets= new int[] { 13, 26 };
		assertComputePartitioning_InterleavingPartitions(13, 26, offsets, DEFAULT);
	}

	@Test
	public void testComputePartitioningSubrangeAfterBoundaries() {
		fDoc.set("docu     ment/* comment *//* comment */docu     ment");

		int[] offsets= new int[] { 26, 26, 39 };
		assertComputePartitioning_InterleavingPartitions(14, 40, offsets, COMMENT);
	}

	@Test
	public void testComputePartitioningSubrangeInBoundaries1() {
		fDoc.set("/* comment */");

		int[] offsets= new int[] { };
		assertComputePartitioning_InterleavingPartitions(1, 12, offsets, COMMENT);
	}

	@Test
	public void testComputePartitioningSubrangeInBoundaries2() {
		fDoc.set("docu     ment");

		int[] offsets= new int[] { };
		assertComputePartitioning_InterleavingPartitions(1, 12, offsets, DEFAULT);
	}

	@Test
	public void testPR101014() throws BadLocationException {
		fDoc.set(
				"package pr101014;\n" +
				"\n" +
				"class X {\n" +
				"String s= \n" +
				"	/*foo*/;\n" +
				"}\n");

		int[] offsets= {41, 48};
		assertComputePartitioning_InterleavingPartitions(offsets);

		fDoc.replace(40, 8, "	/*foo*/");
		assertComputePartitioning_InterleavingPartitions(offsets);
	}

	@Test
	public void testPR130900() throws Exception {
		fPartitioner.disconnect();
		IPartitionTokenScanner scanner= new RuleBasedPartitionScanner() {
			{
				IToken comment= new Token(COMMENT);
				IPredicateRule[] rules= new IPredicateRule[] { new SingleLineRule("#", null, comment, (char) 0, true, false) };
				setPredicateRules(rules);
			}
		};
		fPartitioner= createPartitioner(scanner);
		fDoc.setDocumentPartitioner(fPartitioner);
		fPartitioner.connect(fDoc);

		fDoc.set("#");
		int[] offsets= new int[] { 0, 1 };
		assertComputePartitioning_InterleavingPartitions(offsets);

	}

	@Test
	public void testBug368219_1() throws Exception {
		fPartitioner.disconnect();
		IPartitionTokenScanner scanner= new RuleBasedPartitionScanner() {
			{
				IToken comment= new Token(COMMENT);
				IPredicateRule[] rules= new IPredicateRule[] { new MultiLineRule("/*", "*/", comment) };
				setPredicateRules(rules);
			}
		};
		fPartitioner= createPartitioner(scanner);
		fDoc.setDocumentPartitioner(fPartitioner);
		fPartitioner.connect(fDoc);

		fDoc.set("/**");
		assertEqualPartition(0, 3, DEFAULT);

	}

	@Test
	public void testBug368219_2() throws Exception {
		fPartitioner.disconnect();
		IPartitionTokenScanner scanner= new RuleBasedPartitionScanner() {
			{
				IToken comment= new Token(COMMENT);
				IPredicateRule[] rules= new IPredicateRule[] { new MultiLineRule("/*", "*/", comment, (char)0, true) };
				setPredicateRules(rules);
			}
		};
		fPartitioner= createPartitioner(scanner);
		fDoc.setDocumentPartitioner(fPartitioner);
		fPartitioner.connect(fDoc);

		fDoc.set("/**");
		assertEqualPartition(0, 3, COMMENT);

	}

	@Test
	public void testBug409538_1() throws Exception {
		fPartitioner.disconnect();
		IPartitionTokenScanner scanner= new RuleBasedPartitionScanner() {
			{
				IToken comment= new Token(COMMENT);
				IPredicateRule[] rules= new IPredicateRule[] { new MultiLineRule("<!--", "-->", comment, (char)0, true) };
				setPredicateRules(rules);
			}
		};
		fPartitioner= createPartitioner(scanner);
		fDoc.setDocumentPartitioner(fPartitioner);
		fPartitioner.connect(fDoc);

		fDoc.set("<");
		assertEqualPartition(0, 1, DEFAULT);

	}

	@Test
	public void testBug409538_2() throws Exception {
		fPartitioner.disconnect();
		IPartitionTokenScanner scanner= new RuleBasedPartitionScanner() {
			{
				IToken comment= new Token(COMMENT);
				IPredicateRule[] rules= new IPredicateRule[] { new MultiLineRule("<!--", "-->", comment, (char)0, true) };
				setPredicateRules(rules);
			}
		};
		fPartitioner= createPartitioner(scanner);
		fDoc.setDocumentPartitioner(fPartitioner);
		fPartitioner.connect(fDoc);

		fDoc.set("<!-- blah");
		assertEqualPartition(0, 9, COMMENT);

	}

	private void assertComputePartitioning_InterleavingPartitions(int[] offsets) {
		assertComputePartitioning_InterleavingPartitions(0, fDoc.getLength(), offsets, DEFAULT);
	}

	private void assertComputePartitioning_InterleavingPartitions(int startOffset, int endOffset, int[] offsets, String startType) {
		ITypedRegion[] regions= fPartitioner.computePartitioning(startOffset, endOffset - startOffset);

		String type= startType;
		int previousOffset= startOffset;

		int j= 0;
		for (int i= 0; i <= offsets.length; i++) {
			int currentOffset= (i == offsets.length) ? endOffset : offsets[i];
			if (currentOffset - previousOffset != 0) { // don't do empty partitions
				ITypedRegion region= regions[j++];

				assertTypedRegion(region, previousOffset, currentOffset, type);
			}

			// advance
			if (type == DEFAULT)
				type= COMMENT;
			else
				type= DEFAULT;
			previousOffset= currentOffset;
		}
	}

	private void assertGetContentType_InterleavingPartitions(int[] offsets) {
		String type= DEFAULT;
		int previousOffset= 0;
		for (int i= 0; i <= offsets.length; i++) {
			int offset= (i == offsets.length) ? fDoc.getLength() : offsets[i];
			assertEqualPartitionType(previousOffset, offset, type);

			// advance
			if (type == DEFAULT)
				type= COMMENT;
			else
				type= DEFAULT;
			previousOffset= offset;
		}
	}

	private void assertGetPartition_InterleavingPartitions(int[] offsets) {
		String type= DEFAULT;
		int previousOffset= 0;
		for (int i= 0; i <= offsets.length; i++) {
			int offset= (i == offsets.length) ? fDoc.getLength() : offsets[i];
			assertEqualPartition(previousOffset, offset, type);

			// advance
			if (type == DEFAULT)
				type= COMMENT;
			else
				type= DEFAULT;
			previousOffset= offset;
		}
	}

	private void assertEqualPartition(int offset, int end, String type) {
		int from= offset;
		int to= end - 1;
		for (int i= from; i <= to; i++) {
			ITypedRegion region= fPartitioner.getPartition(i);
			assertTypedRegion(region, offset, end, type);
		}
	}

	private void assertTypedRegion(ITypedRegion region, int offset, int end, String type) {
		assertEquals(offset, region.getOffset());
		assertEquals(end - offset, region.getLength());
		assertEquals(type, region.getType());
	}

	private void assertEqualPartitionType(int offset, int end, String type) {
		int from= offset;
		int to= end - 1;
		for (int i= from; i <= to; i++) {
			assertEquals(type, fPartitioner.getContentType(i));
		}
	}

}
