/*
 * Copyright (C) 2014, Andrey Loskutov <loskutov@gmx.de> and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
package org.eclipse.jgit.ignore.internal;

import static org.eclipse.jgit.ignore.internal.Strings.checkWildCards;
import static org.eclipse.jgit.ignore.internal.Strings.count;
import static org.eclipse.jgit.ignore.internal.Strings.getPathSeparator;
import static org.eclipse.jgit.ignore.internal.Strings.isWildCard;
import static org.eclipse.jgit.ignore.internal.Strings.split;

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

import org.eclipse.jgit.errors.InvalidPatternException;
import org.eclipse.jgit.ignore.IMatcher;
import org.eclipse.jgit.ignore.internal.Strings.PatternState;

/**
 * Matcher built by patterns consists of multiple path segments.
 * <p>
 * This class is immutable and thread safe.
 */
public class PathMatcher extends AbstractMatcher {

	private static final WildMatcher WILD_NO_DIRECTORY = new WildMatcher(false);

	private static final WildMatcher WILD_ONLY_DIRECTORY = new WildMatcher(
			true);

	private final List<IMatcher> matchers;

	private final char slash;

	private final boolean beginning;

	private PathMatcher(String pattern, Character pathSeparator,
			boolean dirOnly)
			throws InvalidPatternException {
		super(pattern, dirOnly);
		slash = getPathSeparator(pathSeparator);
		beginning = pattern.indexOf(slash) == 0;
		if (isSimplePathWithSegments(pattern))
			matchers = null;
		else
			matchers = createMatchers(split(pattern, slash), pathSeparator,
					dirOnly);
	}

	private boolean isSimplePathWithSegments(String path) {
		return !isWildCard(path) && path.indexOf('\\') < 0
				&& count(path, slash, true) > 0;
	}

	private static List<IMatcher> createMatchers(List<String> segments,
			Character pathSeparator, boolean dirOnly)
			throws InvalidPatternException {
		List<IMatcher> matchers = new ArrayList<>(segments.size());
		for (int i = 0; i < segments.size(); i++) {
			String segment = segments.get(i);
			IMatcher matcher = createNameMatcher0(segment, pathSeparator,
					dirOnly, i == segments.size() - 1);
			if (i > 0) {
				final IMatcher last = matchers.get(matchers.size() - 1);
				if (isWild(matcher) && isWild(last))
					// collapse wildmatchers **/** is same as **, but preserve
					// dirOnly flag (i.e. always use the last wildmatcher)
					matchers.remove(matchers.size() - 1);
			}

			matchers.add(matcher);
		}
		return matchers;
	}

	/**
	 * Create path matcher
	 *
	 * @param pattern
	 *            a pattern
	 * @param pathSeparator
	 *            if this parameter isn't null then this character will not
	 *            match at wildcards(* and ? are wildcards).
	 * @param dirOnly
	 *            a boolean.
	 * @return never null
	 * @throws org.eclipse.jgit.errors.InvalidPatternException
	 */
	public static IMatcher createPathMatcher(String pattern,
			Character pathSeparator, boolean dirOnly)
			throws InvalidPatternException {
		pattern = trim(pattern);
		char slash = Strings.getPathSeparator(pathSeparator);
		// ignore possible leading and trailing slash
		int slashIdx = pattern.indexOf(slash, 1);
		if (slashIdx > 0 && slashIdx < pattern.length() - 1)
			return new PathMatcher(pattern, pathSeparator, dirOnly);
		return createNameMatcher0(pattern, pathSeparator, dirOnly, true);
	}

	/**
	 * Trim trailing spaces, unless they are escaped with backslash, see
	 * https://www.kernel.org/pub/software/scm/git/docs/gitignore.html
	 *
	 * @param pattern
	 *            non null
	 * @return trimmed pattern
	 */
	private static String trim(String pattern) {
		while (pattern.length() > 0
				&& pattern.charAt(pattern.length() - 1) == ' ') {
			if (pattern.length() > 1
					&& pattern.charAt(pattern.length() - 2) == '\\') {
				// last space was escaped by backslash: remove backslash and
				// keep space
				pattern = pattern.substring(0, pattern.length() - 2) + " "; //$NON-NLS-1$
				return pattern;
			}
			pattern = pattern.substring(0, pattern.length() - 1);
		}
		return pattern;
	}

	private static IMatcher createNameMatcher0(String segment,
			Character pathSeparator, boolean dirOnly, boolean lastSegment)
			throws InvalidPatternException {
		// check if we see /** or ** segments => double star pattern
		if (WildMatcher.WILDMATCH.equals(segment)
				|| WildMatcher.WILDMATCH2.equals(segment))
			return dirOnly && lastSegment ? WILD_ONLY_DIRECTORY
					: WILD_NO_DIRECTORY;

		PatternState state = checkWildCards(segment);
		switch (state) {
		case LEADING_ASTERISK_ONLY:
			return new LeadingAsteriskMatcher(segment, pathSeparator, dirOnly);
		case TRAILING_ASTERISK_ONLY:
			return new TrailingAsteriskMatcher(segment, pathSeparator, dirOnly);
		case COMPLEX:
			return new WildCardMatcher(segment, pathSeparator, dirOnly);
		default:
			return new NameMatcher(segment, pathSeparator, dirOnly, true);
		}
	}

	/** {@inheritDoc} */
	@Override
	public boolean matches(String path, boolean assumeDirectory,
			boolean pathMatch) {
		if (matchers == null) {
			return simpleMatch(path, assumeDirectory, pathMatch);
		}
		return iterate(path, 0, path.length(), assumeDirectory, pathMatch);
	}

	/*
	 * Stupid but fast string comparison: the case where we don't have to match
	 * wildcards or single segments (mean: this is multi-segment path which must
	 * be at the beginning of the another string)
	 */
	private boolean simpleMatch(String path, boolean assumeDirectory,
			boolean pathMatch) {
		boolean hasSlash = path.indexOf(slash) == 0;
		if (beginning && !hasSlash) {
			path = slash + path;
		}
		if (!beginning && hasSlash) {
			path = path.substring(1);
		}
		if (path.equals(pattern)) {
			// Exact match: must meet directory expectations
			return !dirOnly || assumeDirectory;
		}
		/*
		 * Add slashes for startsWith check. This avoids matching e.g.
		 * "/src/new" to /src/newfile" but allows "/src/new" to match
		 * "/src/new/newfile", as is the git standard
		 */
		String prefix = pattern + slash;
		if (pathMatch) {
			return path.equals(prefix) && (!dirOnly || assumeDirectory);
		}
		if (path.startsWith(prefix)) {
			return true;
		}
		return false;
	}

	/** {@inheritDoc} */
	@Override
	public boolean matches(String segment, int startIncl, int endExcl) {
		throw new UnsupportedOperationException(
				"Path matcher works only on entire paths"); //$NON-NLS-1$
	}

	private boolean iterate(final String path, final int startIncl,
			final int endExcl, boolean assumeDirectory, boolean pathMatch) {
		int matcher = 0;
		int right = startIncl;
		boolean match = false;
		int lastWildmatch = -1;
		// ** matches may get extended if a later match fails. When that
		// happens, we must extend the ** by exactly one segment.
		// wildmatchBacktrackPos records the end of the segment after a **
		// match, so that we can reset correctly.
		int wildmatchBacktrackPos = -1;
		while (true) {
			int left = right;
			right = path.indexOf(slash, right);
			if (right == -1) {
				if (left < endExcl) {
					match = matches(matcher, path, left, endExcl,
							assumeDirectory, pathMatch);
				} else {
					// a/** should not match a/ or a
					match = match && !isWild(matchers.get(matcher));
				}
				if (match) {
					if (matcher < matchers.size() - 1
							&& isWild(matchers.get(matcher))) {
						// ** can match *nothing*: a/**/b match also a/b
						matcher++;
						match = matches(matcher, path, left, endExcl,
								assumeDirectory, pathMatch);
					} else if (dirOnly && !assumeDirectory) {
						// Directory expectations not met
						return false;
					}
				}
				return match && matcher + 1 == matchers.size();
			}
			if (wildmatchBacktrackPos < 0) {
				wildmatchBacktrackPos = right;
			}
			if (right - left > 0) {
				match = matches(matcher, path, left, right, assumeDirectory,
						pathMatch);
			} else {
				// path starts with slash???
				right++;
				continue;
			}
			if (match) {
				boolean wasWild = isWild(matchers.get(matcher));
				if (wasWild) {
					lastWildmatch = matcher;
					wildmatchBacktrackPos = -1;
					// ** can match *nothing*: a/**/b match also a/b
					right = left - 1;
				}
				matcher++;
				if (matcher == matchers.size()) {
					// We had a prefix match here.
					if (!pathMatch) {
						return true;
					}
					if (right == endExcl - 1) {
						// Extra slash at the end: actually a full match.
						// Must meet directory expectations
						return !dirOnly || assumeDirectory;
					}
					// Prefix matches only if pattern ended with /**
					if (wasWild) {
						return true;
					}
					if (lastWildmatch >= 0) {
						// Consider pattern **/x and input x/x.
						// We've matched the prefix x/ so far: we
						// must try to extend the **!
						matcher = lastWildmatch + 1;
						right = wildmatchBacktrackPos;
						wildmatchBacktrackPos = -1;
					} else {
						return false;
					}
				}
			} else if (lastWildmatch != -1) {
				matcher = lastWildmatch + 1;
				right = wildmatchBacktrackPos;
				wildmatchBacktrackPos = -1;
			} else {
				return false;
			}
			right++;
		}
	}

	private boolean matches(int matcherIdx, String path, int startIncl,
			int endExcl, boolean assumeDirectory, boolean pathMatch) {
		IMatcher matcher = matchers.get(matcherIdx);

		final boolean matches = matcher.matches(path, startIncl, endExcl);
		if (!matches || !pathMatch || matcherIdx < matchers.size() - 1
				|| !(matcher instanceof AbstractMatcher)) {
			return matches;
		}

		return assumeDirectory || !((AbstractMatcher) matcher).dirOnly;
	}

	private static boolean isWild(IMatcher matcher) {
		return matcher == WILD_NO_DIRECTORY || matcher == WILD_ONLY_DIRECTORY;
	}
}
