package org.eclipse.dltk.ui.text.heredoc;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IPredicateRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.RuleBasedPartitionScanner;

/**
 * A slightly modified version of a <code>RuleBasedPartitionScanner</code> that
 * knows how to properly scan for heredoc partitions.
 *
 * <p>
 * There is no need to use this partition scanner if heredoc is not supported by
 * the underlying dynamic language.
 * </p>
 *
 * <p>
 * If you do use this partitioner, you <b>must</b> also use the
 * <code>HereDocEnabledPartitioner</code> partitioner as it knows how to
 * properly manage heredoc partitions.
 * </p>
 *
 * @see HereDocPartitionRule
 * @see HereDocEnabledPartitioner
 * @see HereDocEnabledPresentationReconciler
 */
public class HereDocEnabledPartitionScanner extends RuleBasedPartitionScanner {
	private List<TokenContainer> buffer = new ArrayList<>();

	private HereDocPartitionRule hereDocRule;

	/**
	 * Creates a new heredoc partition scanner
	 * 
	 * @param rules
	 *            list of predicate rules that should be used to create document
	 *            partitions
	 * @param hereDocRule
	 *            heredoc partitioning rule
	 */
	public HereDocEnabledPartitionScanner(List<IPredicateRule> rules,
			HereDocPartitionRule hereDocRule) {
		this.hereDocRule = hereDocRule;

		IPredicateRule[] result = new IPredicateRule[rules.size()];
		setPredicateRules(rules.toArray(result));
	}

	@Override
	public IToken nextToken() {
		if (HereDocUtils.isHereDocContent(fContentType)) {
			return handleHereDoc();
		}

		if (!buffer.isEmpty()) {
			return buffer.remove(0).getToken();
		}

		return getNextToken(false);
	}

	@Override
	public void setPartialRange(IDocument document, int offset, int length,
			String contentType, int partitionOffset) {
		/*
		 * clear out any tokens that may be sitting in the buffer before the
		 * 'nextToken()' is requested. this method is only called if the
		 * document changes, which means the 'manual' rule should be passed all
		 * the information it needs to finish it's evaluation piggy-backed off
		 * the passed content type.
		 */
		buffer.clear();
		super.setPartialRange(document, offset, length, contentType,
				partitionOffset);
	}

	private IToken evalPossibleHereDoc(boolean inScan) {
		// our token is going to start wherever the scanner is
		fTokenOffset = fOffset;

		IToken token = hereDocRule.evaluate(this);

		if (token.isUndefined() || inScan) {
			return token;
		}

		buffer.add(new TokenContainer(token));

		int c;
		while ((c = read()) != ICharacterScanner.EOF) {
			unread();

			IToken next = getNextToken(true);
			buffer.add(new TokenContainer(next));

			if (c == '\n') {
				break;
			}
		}

		if (c != ICharacterScanner.EOF) {
			consumeHereDoc();
		}

		return buffer.remove(0).getToken();
	}

	private void consumeHereDoc() {
		// need to work w/ a copy otherwise we get concurrent modification
		// exception
		for (TokenContainer container : new ArrayList<>(buffer)) {
			if (HereDocUtils.isHereDocContent(container.getContentType())) {
				fTokenOffset = fOffset;
				fColumn = UNDEFINED;

				IToken body = hereDocRule.evaluate(this,
						container.getContentType());
				buffer.add(new TokenContainer(body));
			}
		}
	}

	private IToken getNextToken(boolean inScan) {
		IToken token = evalPossibleHereDoc(inScan);
		if (token.isUndefined()) {
			token = super.nextToken();
		}

		return token;
	}

	private IToken handleHereDoc() {
		// reset to partition start so we get all the characters
		fTokenOffset = fPartitionOffset;

		IToken token = hereDocRule.evaluate(this, fContentType);

		// we found our rule, reset the contentType just like our parent would
		fContentType = null;
		return token;
	}

	private class TokenContainer {
		private int offset;
		private IToken token;
		private int tokenOffset;

		TokenContainer(IToken token) {
			this.offset = fOffset;
			this.tokenOffset = fTokenOffset;

			this.token = token;
		}

		String getContentType() {
			return (String) token.getData();
		}

		IToken getToken() {
			fOffset = offset;
			fTokenOffset = tokenOffset;

			return token;
		}
	}
}
