/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.e4.tools.emf.ui.internal;

import java.util.Vector;

/**
 * A string pattern matcher, suppporting "*" and "?" wildcards.
 */
public class StringMatcher {
	protected String fPattern;

	protected int fLength; // pattern length

	protected boolean fIgnoreWildCards;

	protected boolean fIgnoreCase;

	protected boolean fHasLeadingStar;

	protected boolean fHasTrailingStar;

	protected String fSegments[]; // the given pattern is split into * separated
	// segments

	/* boundary value beyond which we don't need to search in the text */
	protected int fBound = 0;

	protected static final char fSingleWildCard = '\u0000';

	public static class Position {
		int start; // inclusive

		int end; // exclusive

		public Position(int start, int end) {
			this.start = start;
			this.end = end;
		}

		public int getStart() {
			return start;
		}

		public int getEnd() {
			return end;
		}
	}

	/**
	 * StringMatcher constructor takes in a String object that is a simple
	 * pattern which may contain '*' for 0 and many characters and '?' for
	 * exactly one character.
	 *
	 * Literal '*' and '?' characters must be escaped in the pattern e.g.,
	 * "\*" means literal "*", etc.
	 *
	 * Escaping any other character (including the escape character itself),
	 * just results in that character in the pattern. e.g., "\a" means "a" and
	 * "\\" means "\"
	 *
	 * If invoking the StringMatcher with string literals in Java, don't forget
	 * escape characters are represented by "\\".
	 *
	 * @param pattern
	 *            the pattern to match text against
	 * @param ignoreCase
	 *            if true, case is ignored
	 * @param ignoreWildCards
	 *            if true, wild cards and their escape sequences are ignored
	 *            (everything is taken literally).
	 */
	public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
		if (pattern == null) {
			throw new IllegalArgumentException();
		}
		fIgnoreCase = ignoreCase;
		fIgnoreWildCards = ignoreWildCards;
		fPattern = pattern;
		fLength = pattern.length();

		if (fIgnoreWildCards) {
			parseNoWildCards();
		} else {
			parseWildCards();
		}
	}

	/**
	 * Find the first occurrence of the pattern between <code>start</code )(inclusive) and <code>end</code>(exclusive).
	 *
	 * @param text
	 *            the String object to search in
	 * @param start
	 *            the starting index of the search range, inclusive
	 * @param end
	 *            the ending index of the search range, exclusive
	 * @return an <code>StringMatcher.Position</code> object that keeps the
	 *         starting (inclusive) and ending positions (exclusive) of the
	 *         first occurrence of the pattern in the specified range of the
	 *         text; return null if not found or subtext is empty (start==end).
	 *         A pair of zeros is returned if pattern is empty string Note that
	 *         for pattern like "*abc*" with leading and trailing stars,
	 *         position of "abc" is returned. For a pattern like"*??*" in text
	 *         "abcdf", (1,3) is returned
	 */
	public StringMatcher.Position find(String text, int start, int end) {
		if (text == null) {
			throw new IllegalArgumentException();
		}

		final int tlen = text.length();
		if (start < 0) {
			start = 0;
		}
		if (end > tlen) {
			end = tlen;
		}
		if (end < 0 || start >= end) {
			return null;
		}
		if (fLength == 0) {
			return new Position(start, start);
		}
		if (fIgnoreWildCards) {
			final int x = posIn(text, start, end);
			if (x < 0) {
				return null;
			}
			return new Position(x, x + fLength);
		}

		final int segCount = fSegments.length;
		if (segCount == 0) {
			return new Position(start, end);
		}

		int curPos = start;
		int matchStart = -1;
		int i;
		for (i = 0; i < segCount && curPos < end; ++i) {
			final String current = fSegments[i];
			final int nextMatch = regExpPosIn(text, curPos, end, current);
			if (nextMatch < 0) {
				return null;
			}
			if (i == 0) {
				matchStart = nextMatch;
			}
			curPos = nextMatch + current.length();
		}
		if (i < segCount) {
			return null;
		}
		return new Position(matchStart, curPos);
	}

	/**
	 * match the given <code>text</code> with the pattern
	 *
	 * @return true if matched otherwise false
	 * @param text
	 *            a String object
	 */
	public boolean match(String text) {
		if (text == null) {
			return false;
		}
		return match(text, 0, text.length());
	}

	/**
	 * Given the starting (inclusive) and the ending (exclusive) positions in
	 * the <code>text</code>, determine if the given substring matches with
	 * aPattern
	 *
	 * @return true if the specified portion of the text matches the pattern
	 * @param text
	 *            a String object that contains the substring to match
	 * @param start
	 *            marks the starting position (inclusive) of the substring
	 * @param end
	 *            marks the ending index (exclusive) of the substring
	 */
	public boolean match(String text, int start, int end) {
		if (null == text) {
			throw new IllegalArgumentException();
		}

		if (start > end) {
			return false;
		}

		if (fIgnoreWildCards) {
			return end - start == fLength && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength);
		}
		final int segCount = fSegments.length;
		if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) {
			return true;
		}
		if (start == end) {
			return fLength == 0;
		}
		if (fLength == 0) {
			return start == end;
		}

		final int tlen = text.length();
		if (start < 0) {
			start = 0;
		}
		if (end > tlen) {
			end = tlen;
		}

		int tCurPos = start;
		final int bound = end - fBound;
		if (bound < 0) {
			return false;
		}
		int i = 0;
		String current = fSegments[i];
		final int segLength = current.length();

		/* process first segment */
		if (!fHasLeadingStar) {
			if (!regExpRegionMatches(text, start, current, 0, segLength)) {
				return false;
			}
			++i;
			tCurPos = tCurPos + segLength;
		}
		if (fSegments.length == 1 && !fHasLeadingStar && !fHasTrailingStar) {
			// only one segment to match, no wildcards specified
			return tCurPos == end;
		}
		/* process middle segments */
		while (i < segCount) {
			current = fSegments[i];
			int currentMatch;
			final int k = current.indexOf(fSingleWildCard);
			if (k < 0) {
				currentMatch = textPosIn(text, tCurPos, end, current);
				if (currentMatch < 0) {
					return false;
				}
			} else {
				currentMatch = regExpPosIn(text, tCurPos, end, current);
				if (currentMatch < 0) {
					return false;
				}
			}
			tCurPos = currentMatch + current.length();
			i++;
		}

		/* process final segment */
		if (!fHasTrailingStar && tCurPos != end) {
			final int clen = current.length();
			return regExpRegionMatches(text, end - clen, current, 0, clen);
		}
		return i == segCount;
	}

	/**
	 * This method parses the given pattern into segments seperated by wildcard
	 * '*' characters. Since wildcards are not being used in this case, the
	 * pattern consists of a single segment.
	 */
	private void parseNoWildCards() {
		fSegments = new String[1];
		fSegments[0] = fPattern;
		fBound = fLength;
	}

	/**
	 * Parses the given pattern into segments seperated by wildcard '*'
	 * characters.
	 *
	 * @param p
	 *            , a String object that is a simple regular expression with '*'
	 *            and/or '?'
	 */
	private void parseWildCards() {
		if (fPattern.startsWith("*")) { //$NON-NLS-1$
			fHasLeadingStar = true;
		}
		if (fPattern.endsWith("*")) {//$NON-NLS-1$
			/* make sure it's not an escaped wildcard */
			if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {
				fHasTrailingStar = true;
			}
		}

		final Vector<String> temp = new Vector<>();

		int pos = 0;
		final StringBuffer buf = new StringBuffer();
		while (pos < fLength) {
			final char c = fPattern.charAt(pos++);
			switch (c) {
			case '\\':
				if (pos >= fLength) {
					buf.append(c);
				} else {
					final char next = fPattern.charAt(pos++);
					/* if it's an escape sequence */
					if (next == '*' || next == '?' || next == '\\') {
						buf.append(next);
					} else {
						/* not an escape sequence, just insert literally */
						buf.append(c);
						buf.append(next);
					}
				}
				break;
			case '*':
				if (buf.length() > 0) {
					/* new segment */
					temp.addElement(buf.toString());
					fBound += buf.length();
					buf.setLength(0);
				}
				break;
			case '?':
				/* append special character representing single match wildcard */
				buf.append(fSingleWildCard);
				break;
			default:
				buf.append(c);
			}
		}

		/* add last buffer to segment list */
		if (buf.length() > 0) {
			temp.addElement(buf.toString());
			fBound += buf.length();
		}

		fSegments = new String[temp.size()];
		temp.copyInto(fSegments);
	}

	/**
	 * @param text
	 *            a string which contains no wildcard
	 * @param start
	 *            the starting index in the text for search, inclusive
	 * @param end
	 *            the stopping point of search, exclusive
	 * @return the starting index in the text of the pattern , or -1 if not
	 *         found
	 */
	protected int posIn(String text, int start, int end) {// no wild card in
		// pattern
		final int max = end - fLength;

		if (!fIgnoreCase) {
			final int i = text.indexOf(fPattern, start);
			if (i == -1 || i > max) {
				return -1;
			}
			return i;
		}

		for (int i = start; i <= max; ++i) {
			if (text.regionMatches(true, i, fPattern, 0, fLength)) {
				return i;
			}
		}

		return -1;
	}

	/**
	 * @param text
	 *            a simple regular expression that may only contain '?'(s)
	 * @param start
	 *            the starting index in the text for search, inclusive
	 * @param end
	 *            the stopping point of search, exclusive
	 * @param p
	 *            a simple regular expression that may contains '?'
	 * @return the starting index in the text of the pattern , or -1 if not
	 *         found
	 */
	protected int regExpPosIn(String text, int start, int end, String p) {
		final int plen = p.length();

		final int max = end - plen;
		for (int i = start; i <= max; ++i) {
			if (regExpRegionMatches(text, i, p, 0, plen)) {
				return i;
			}
		}
		return -1;
	}

	/**
	 *
	 * @return boolean
	 * @param text
	 *            a String to match
	 * @param start
	 *            int that indicates the starting index of match, inclusive
	 * @param end
	 *            </code> int that indicates the ending index of match,
	 *            exclusive
	 * @param p
	 *            String, String, a simple regular expression that may contain
	 *            '?'
	 * @param ignoreCase
	 *            boolean indicating wether code>p</code> is case sensitive
	 */
	protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) {
		while (plen-- > 0) {
			final char tchar = text.charAt(tStart++);
			final char pchar = p.charAt(pStart++);

			/* process wild cards */
			if (!fIgnoreWildCards) {
				/* skip single wild cards */
				if (pchar == fSingleWildCard) {
					continue;
				}
			}
			if (pchar == tchar) {
				continue;
			}
			if (fIgnoreCase) {
				if (Character.toUpperCase(tchar) == Character.toUpperCase(pchar)) {
					continue;
				}
				// comparing after converting to upper case doesn't handle all
				// cases;
				// also compare after converting to lower case
				if (Character.toLowerCase(tchar) == Character.toLowerCase(pchar)) {
					continue;
				}
			}
			return false;
		}
		return true;
	}

	/**
	 * @param text
	 *            the string to match
	 * @param start
	 *            the starting index in the text for search, inclusive
	 * @param end
	 *            the stopping point of search, exclusive
	 * @param p
	 *            a pattern string that has no wildcard
	 * @return the starting index in the text of the pattern , or -1 if not
	 *         found
	 */
	protected int textPosIn(String text, int start, int end, String p) {

		final int plen = p.length();
		final int max = end - plen;

		if (!fIgnoreCase) {
			final int i = text.indexOf(p, start);
			if (i == -1 || i > max) {
				return -1;
			}
			return i;
		}

		for (int i = start; i <= max; ++i) {
			if (text.regionMatches(true, i, p, 0, plen)) {
				return i;
			}
		}

		return -1;
	}
}
