/*******************************************************************************
 * Copyright (c) 2007, 2015 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.text.tests;

import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

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

import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.jface.text.source.IAnnotationModelListener;

/**
 * Tests the {@link org.eclipse.jface.text.source.IAnnotationModelExtension2}.
 *
 * @since 3.4
 */
public class AnnotationModelExtension2Test {

	public class OldAnnotationModel implements IAnnotationModel {

		private final HashMap<Annotation, Position> fAnnotations= new HashMap<>();

		@Override
		public void addAnnotation(Annotation annotation, Position position) {
			fAnnotations.put(annotation, position);
		}

		@Override
		public void addAnnotationModelListener(IAnnotationModelListener listener) {
		}

		@Override
		public void connect(IDocument document) {
		}

		@Override
		public void disconnect(IDocument document) {
		}

		@Override
		public Iterator<Annotation> getAnnotationIterator() {
			return fAnnotations.keySet().iterator();
		}

		@Override
		public Position getPosition(Annotation annotation) {
			return fAnnotations.get(annotation);
		}

		@Override
		public void removeAnnotation(Annotation annotation) {
			fAnnotations.remove(annotation);
		}

		@Override
		public void removeAnnotationModelListener(IAnnotationModelListener listener) {
		}

		public void removeAllAnnotations() {
			fAnnotations.clear();
		}
	}

	private static final int MODEL_COUNT= 3;

	private Document fDocument;
	private AnnotationModel fAnnotationModel;
	private AnnotationModel fNewInnerModel;
	private OldAnnotationModel fOldInnerModel;

	private Annotation fInside;
	private Annotation fBefore;
	private Annotation fAfter;
	private Annotation fInsideIn;
	private Annotation fInsideOut;
	private Annotation fBeforeIn;
	private Annotation fBoforeOut;
	private Annotation fAfterIn;
	private Annotation fAfterOut;

	@Before
	public void setUp() {
		fDocument= new Document("How much wood\nwould a woodchuck chuck\nif a woodchuck\ncould chuck wood?\n42");

		fAnnotationModel= new AnnotationModel();

		fNewInnerModel= new AnnotationModel();
		fAnnotationModel.addAnnotationModel("model1", fNewInnerModel);

		fOldInnerModel= new OldAnnotationModel();
		fAnnotationModel.addAnnotationModel("model2", fOldInnerModel);

		fInside= new Annotation(false);
		fInsideIn= new Annotation(false);
		fInsideOut= new Annotation(false);

		fBefore= new Annotation(false);
		fBeforeIn= new Annotation(false);
		fBoforeOut= new Annotation(false);

		fAfter= new Annotation(false);
		fAfterIn= new Annotation(false);
		fAfterOut= new Annotation(false);

		fAnnotationModel.connect(fDocument);
	}

	@After
	public void tearDown() {
		fAnnotationModel.disconnect(fDocument);
	}

	private void assertEquals(Annotation[] expected, Annotation[] actual, IAnnotationModel insideModel, IAnnotationModel beforeModel, IAnnotationModel afterModel) {
		HashSet<Annotation> expectedSet= new HashSet<>(Arrays.asList(expected));
		for (Annotation a : actual) {
			if (!expectedSet.contains(a)) {
				String message = "Unexpected annotation " + getName(a) + " in result with models [" + getAnnotationModelNames(insideModel, beforeModel, afterModel) + "]";
				assertTrue(message, false);
			}
			expectedSet.remove(a);
		}

		if (!expectedSet.isEmpty()) {
			String message= "Missing annotations in result with models [" + getAnnotationModelNames(insideModel, beforeModel, afterModel) + "]";
			for (Annotation missing : expectedSet) {
				message= message + "\n" + getName(missing);
			}
			assertTrue(message, false);
		}
	}

	private String getAnnotationModelNames(IAnnotationModel insideModel, IAnnotationModel beforeModel, IAnnotationModel afterModel) {
		return "inside: " + getAnnotationModelName(insideModel) + " before: " + getAnnotationModelName(beforeModel) + " after: " + getAnnotationModelName(afterModel);
	}

	private String getAnnotationModelName(IAnnotationModel model) {
		if (model == fAnnotationModel) {
			return "'Top'";
		} else if (model == fNewInnerModel) {
			return "'New inner'";
		} else if (model == fOldInnerModel) {
			return "'Old inner'";
		}

		return "'Unknown'";
	}

	private String getName(Annotation annotation) {
		Position position= fAnnotationModel.getPosition(annotation);
		return "[" + position.getOffset() + ", " + position.getLength() + "]";
	}

	/*
	 * The annotations are added to the annotations models
	 * as following:
	 *
	 * 0-beforeout-9               21-afterout--30
	 * 0--beforein---11          19---afterin---30
	 * 0--before----10            20--after-----30
	 *
	 *              10--region----20
	 *
	 *              10--inside----20
	 *               11-insidein-19
	 *             9---insideout---21
	 */
	private void addAnnotations(IAnnotationModel insideModel, IAnnotationModel beforeModel, IAnnotationModel afterModel) {
		insideModel.addAnnotation(fInside, new Position(10, 11));
		insideModel.addAnnotation(fInsideIn, new Position(11, 9));
		insideModel.addAnnotation(fInsideOut, new Position(9, 13));

		beforeModel.addAnnotation(fBefore, new Position(0, 11));
		beforeModel.addAnnotation(fBeforeIn, new Position(0, 12));
		beforeModel.addAnnotation(fBoforeOut, new Position(0, 10));

		afterModel.addAnnotation(fAfter, new Position(20, 11));
		afterModel.addAnnotation(fAfterIn, new Position(19, 12));
		afterModel.addAnnotation(fAfterOut, new Position(21, 10));
	}

	private void removeAnnotations() {
		fAnnotationModel.removeAllAnnotations();
		fNewInnerModel.removeAllAnnotations();
		fOldInnerModel.removeAllAnnotations();
	}

	private Annotation[] getAnnotations(boolean lookAhead, boolean lookBehind) {
		Iterator<Annotation> iterator= fAnnotationModel.getAnnotationIterator(10, 11, lookAhead, lookBehind);

		ArrayList<Annotation> result= new ArrayList<>();
		while (iterator.hasNext()) {
			result.add(iterator.next());
		}

		return result.toArray(new Annotation[result.size()]);
	}

	private void assertPermutations(boolean lookAhead, boolean lookBehind, Annotation[] expected) {
		for (int i= 0; i < MODEL_COUNT; i++) {
			for (int j= 0; j < MODEL_COUNT; j++) {
				for (int k= 0; k < MODEL_COUNT; k++) {
					IAnnotationModel insideModel= getModel(i);
					IAnnotationModel beforeModel= getModel(j);
					IAnnotationModel afterModel= getModel(k);

					addAnnotations(insideModel, beforeModel, afterModel);

					Annotation[] actual= getAnnotations(lookAhead, lookBehind);
					assertEquals(expected, actual, insideModel, beforeModel, afterModel);

					removeAnnotations();
				}
			}
		}
	}

	private IAnnotationModel getModel(int number) {
		switch (number) {
			case 0:
				return fAnnotationModel;
			case 1:
				return fNewInnerModel;
			case 2:
				return fOldInnerModel;
			default:
				break;
		}
		return null;
	}

	@Test
	public void testInside() throws Exception {
		Annotation[] expected= new Annotation[] { fInside, fInsideIn };
		assertPermutations(false, false, expected);
	}

	@Test
	public void testAhead() throws Exception {
		Annotation[] expected= new Annotation[] { fInside, fInsideIn, fBefore, fBeforeIn };
		assertPermutations(true, false, expected);
	}

	@Test
	public void testBehind() throws Exception {
		Annotation[] expected= new Annotation[] { fInside, fInsideIn, fAfter, fAfterIn };
		assertPermutations(false, true, expected);
	}

	@Test
	public void testAheadBehind() throws Exception {
		Annotation[] expected= new Annotation[] { fInside, fInsideIn, fInsideOut, fAfter, fAfterIn, fBefore, fBeforeIn };
		assertPermutations(true, true, expected);
	}

}
