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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.core.runtime.Assert;

import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;


/**
 * A group of positions in multiple documents that are simultaneously modified -
 * if one gets edited, all other positions in a group are edited the same way.
 * <p>
 * All linked positions in a group should have the same content.
 * Before 3.5.400, this was enforced. Now, if one position of a mixed group gets edited,
 * the content of all other positions is replaced by the edited position's content.
 * </p>
 * <p>
 * Normally, new positions are given a {@link LinkedPosition#getSequenceNumber() sequence number} which can be used by
 * clients, e.g. in the UI as tab stop weight. If {@link #NO_STOP} is used as weight, a position will not be visited.
 * If {@link #NO_STOP} is used for all positions, the first position in a document is taken as
 * the only stop as to comply with the behavior of the old linked position
 * infrastructure.
 * </p>
 * <p>
 * Clients may instantiate this class.
 * </p>
 *
 * @since 3.0
 * @noextend This class is not intended to be subclassed by clients.
 */
public class LinkedPositionGroup {

	/** {@link LinkedPosition#getSequenceNumber() Sequence number} constant declaring that a position should not be stopped by. */
	public static final int NO_STOP= -1;

	/* members */

	/** The linked positions of this group. */
	private final List<LinkedPosition> fPositions= new LinkedList<>();
	/** Whether we are sealed or not. */
	private boolean fIsSealed= false;
	/**
	 * <code>true</code> if there are custom iteration weights. For backward
	 * compatibility.
	 */
	private boolean fHasCustomIteration= false;

	/*
	 * iteration variables, set to communicate state between isLegalEvent and
	 * handleEvent
	 */
	/** The position including the most recent <code>DocumentEvent</code>. */
	private LinkedPosition fLastPosition;
	/** The region covered by <code>fLastPosition</code> before the document
	 * change.
	 */
	private IRegion fLastRegion;

	/**
	 * <code>true</code> iff not all positions contain the same content.
	 * In that case, the contents of the last edited position will replace the
	 * contents of all other linked positions.
	 */
	private boolean fMustEnforceEqualContents= false;

	/**
	 * Adds a position to this group. The document region defined by the
	 * position should contain the same content as all of the other positions
	 * already in this group.
	 * All positions added must be valid and disjoint; otherwise a
	 * <code>BadLocationException</code> is thrown.
	 * <p>
	 * Positions added using this method are owned by this group afterwards and
	 * may not be updated or modified thereafter.
	 * </p>
	 * <p>
	 * Once a group has been added to a <code>LinkedModeModel</code>, it
	 * becomes <em>sealed</em> and no positions may be added any more.
	 * </p>
	 *
	 * @param position the position to add
	 * @throws BadLocationException if the position is invalid or conflicts with
	 *         other positions in the group
	 * @throws IllegalStateException if the group has already been added to a
	 *         model
	 */
	public void addPosition(LinkedPosition position) throws BadLocationException {
		/*
		 * Enforces constraints and sets the custom iteration flag. If the
		 * position is already in this group, nothing happens.
		 */
		Assert.isNotNull(position);
		if (fIsSealed)
			throw new IllegalStateException("cannot add positions after the group is added to an model"); //$NON-NLS-1$

		if (!fPositions.contains(position)) {
			enforceDisjoint(position);
			checkContent(position);
			fPositions.add(position);
			fHasCustomIteration |= position.getSequenceNumber() != LinkedPositionGroup.NO_STOP;
		} else
			return; // nothing happens
	}

	/**
	 * Checks whether all positions contain the same string as the given position.
	 * If not, then {@link #fMustEnforceEqualContents} is set to <code>true</code>.
	 *
	 * @param position the position to check
	 * @throws BadLocationException if the position is invalid
	 */
	private void checkContent(LinkedPosition position) throws BadLocationException {
		if (fPositions.size() > 0) {
			LinkedPosition groupPosition= fPositions.get(0);
			String groupContent= groupPosition.getContent();
			String positionContent= position.getContent();
			if (!fMustEnforceEqualContents && !groupContent.equals(positionContent)) {
				fMustEnforceEqualContents= true;
			}
		}
	}

	/**
	 * Enforces the invariant that all positions must be disjoint.
	 *
	 * @param position the position to check
	 * @throws BadLocationException if the disjointness check fails
	 */
	private void enforceDisjoint(LinkedPosition position) throws BadLocationException {
		for (LinkedPosition p : fPositions) {
			if (p.overlapsWith(position))
				throw new BadLocationException();
		}
	}

	/**
	 * Enforces the disjointness for another group
	 *
	 * @param group the group to check
	 * @throws BadLocationException if the disjointness check fails
	 */
	void enforceDisjoint(LinkedPositionGroup group) throws BadLocationException {
		Assert.isNotNull(group);
		for (LinkedPosition p : group.fPositions) {
			enforceDisjoint(p);
		}
	}

	/**
	 * Checks whether <code>event</code> is a legal event for this group. An
	 * event is legal if it touches at most one position contained within this
	 * group.
	 *
	 * @param event the document event to check
	 * @return <code>true</code> if <code>event</code> is legal
	 */
	boolean isLegalEvent(DocumentEvent event) {
		fLastPosition= null;
		fLastRegion= null;

		for (LinkedPosition pos : fPositions) {
			if (overlapsOrTouches(pos, event)) {
				if (fLastPosition != null) {
					fLastPosition= null;
					fLastRegion= null;
					return false;
				}

				fLastPosition= pos;
				fLastRegion= new Region(pos.getOffset(), pos.getLength());
			}
		}

		return true;
	}

	/**
	 * Checks whether the given event touches the given position. To touch means
	 * to overlap or come up to the borders of the position.
	 *
	 * @param position the position
	 * @param event the event
	 * @return <code>true</code> if <code>position</code> and
	 *         <code>event</code> are not absolutely disjoint
	 * @since 3.1
	 */
	private boolean overlapsOrTouches(LinkedPosition position, DocumentEvent event) {
		return position.getDocument().equals(event.getDocument()) && position.getOffset() <= event.getOffset() + event.getLength() && position.getOffset() + position.getLength() >= event.getOffset();
	}

	/**
	 * Creates an edition of a document change that will forward any
	 * modification in one position to all linked siblings. The return value is
	 * a map from <code>IDocument</code> to <code>TextEdit</code>.
	 *
	 * @param event the document event to check
	 * @return a map of edits, grouped by edited document, or <code>null</code>
	 *         if there are no edits
	 */
	Map<IDocument, TextEdit> handleEvent(DocumentEvent event) {

		if (fLastPosition != null) {

			Map<IDocument, List<ReplaceEdit>> map= new HashMap<>();


			int relativeOffset= event.getOffset() - fLastRegion.getOffset();
			if (relativeOffset < 0) {
				relativeOffset= 0;
			}

			int eventEnd= event.getOffset() + event.getLength();
			int lastEnd= fLastRegion.getOffset() + fLastRegion.getLength();
			int length;
			if (eventEnd > lastEnd)
				length= lastEnd - relativeOffset - fLastRegion.getOffset();
			else
				length= eventEnd - relativeOffset - fLastRegion.getOffset();

			String text= event.getText();
			if (text == null)
				text= ""; //$NON-NLS-1$

			for (LinkedPosition p : fPositions) {
				if (p == fLastPosition || p.isDeleted())
					continue; // don't re-update the origin of the change

				List<ReplaceEdit> edits= map.get(p.getDocument());
				if (edits == null) {
					edits= new ArrayList<>();
					map.put(p.getDocument(), edits);
				}

				if (fMustEnforceEqualContents) {
					try {
						edits.add(new ReplaceEdit(p.getOffset(), p.getLength(), fLastPosition.getContent()));
					} catch (BadLocationException e) {
						throw new RuntimeException(e); // should not happen
					}
				} else {
					edits.add(new ReplaceEdit(p.getOffset() + relativeOffset, length, text));
				}
			}
			fMustEnforceEqualContents= false;

			try {
				Map<IDocument, TextEdit> result= new HashMap<>();
				for (Entry<IDocument, List<ReplaceEdit>> edits : map.entrySet()) {
					TextEdit edit= new MultiTextEdit(0, edits.getKey().getLength());
					edit.addChildren(edits.getValue().toArray(new TextEdit[edits.getValue().size()]));
					result.put(edits.getKey(), edit);
				}

				return result;
			} catch (MalformedTreeException x) {
				// may happen during undo, as LinkedModeModel does not know
				// that the changes technically originate from a parent environment
				// if this happens, post notification changes are not accepted anyway and
				// we can simply return null - any changes will be undone by the undo
				// manager
				return null;
			}

		}

		return null;
	}

	/**
	 * Sets the model of this group. Once a model has been set, no
	 * more positions can be added and the model cannot be changed.
	 */
	void seal() {
		Assert.isTrue(!fIsSealed);
		fIsSealed= true;

		if (fHasCustomIteration == false && fPositions.size() > 0) {
			fPositions.get(0).setSequenceNumber(0);
		}
	}

	IDocument[] getDocuments() {
		IDocument[] docs= new IDocument[fPositions.size()];
		int i= 0;
		for (Iterator<LinkedPosition> it= fPositions.iterator(); it.hasNext(); i++) {
			LinkedPosition pos= it.next();
			docs[i]= pos.getDocument();
		}
		return docs;
	}

	void register(LinkedModeModel model) throws BadLocationException {
		for (LinkedPosition pos : fPositions) {
			model.register(pos);
		}
	}

	/**
	 * Returns the position in this group that encompasses all positions in
	 * <code>group</code>.
	 *
	 * @param group the group to be adopted
	 * @return a position in the receiver that contains all positions in <code>group</code>,
	 *         or <code>null</code> if none can be found
	 * @throws BadLocationException if more than one position are affected by
	 *         <code>group</code>
	 */
	LinkedPosition adopt(LinkedPositionGroup group) throws BadLocationException {
		LinkedPosition found= null;
		for (LinkedPosition pos : group.fPositions) {
			LinkedPosition localFound= null;
			for (LinkedPosition myPos : fPositions) {
				if (myPos.includes(pos)) {
					if (found == null)
						found= myPos;
					else if (found != myPos)
						throw new BadLocationException();
					if (localFound == null)
						localFound= myPos;
				}
			}

			if (localFound != found)
				throw new BadLocationException();
		}
		return found;
	}

	/**
	 * Finds the closest position to <code>toFind</code>.
	 *
	 * @param toFind the linked position for which to find the closest position
	 * @return the closest position to <code>toFind</code>.
	 */
	LinkedPosition getPosition(LinkedPosition toFind) {
		for (LinkedPosition p : fPositions) {
			if (p.includes(toFind))
				return p;
		}
		return null;
	}

	/**
	 * Returns <code>true</code> if <code>offset</code> is contained in any
	 * position in this group.
	 *
	 * @param offset the offset to check
	 * @return <code>true</code> if offset is contained by this group
	 */
	boolean contains(int offset) {
		for (LinkedPosition pos : fPositions) {
			if (pos.includes(offset)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Returns whether this group contains any positions.
	 *
	 * @return <code>true</code> if this group is empty, <code>false</code> otherwise
	 * @since 3.1
	 */
	public boolean isEmpty() {
		return fPositions.size() == 0;
	}

	/**
	 * Returns whether this group contains any positions.
	 *
	 * @return <code>true</code> if this group is empty, <code>false</code> otherwise
	 * @deprecated As of 3.1, replaced by {@link #isEmpty()}
	 */
	@Deprecated
	public boolean isEmtpy() {
		return isEmpty();
	}

	/**
	 * Returns the positions contained in the receiver as an array. The
	 * positions are the actual positions and must not be modified; the array
	 * is a copy of internal structures.
	 *
	 * @return the positions of this group in no particular order
	 */
	public LinkedPosition[] getPositions() {
		return fPositions.toArray(new LinkedPosition[0]);
	}

	/**
	 * Returns <code>true</code> if the receiver contains <code>position</code>.
	 *
	 * @param position the position to check
	 * @return <code>true</code> if the receiver contains <code>position</code>
	 */
	boolean contains(Position position) {
		for (LinkedPosition p : fPositions) {
			if (position.equals(p))
				return true;
		}
		return false;
	}
}
