/*
 * Copyright (C) 2014, Andrey Loskutov <loskutov@gmx.de>
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.eclipse.jgit.ignore;

import static org.eclipse.jgit.ignore.internal.IMatcher.NO_MATCH;
import static org.eclipse.jgit.ignore.internal.Strings.isDirectoryPattern;
import static org.eclipse.jgit.ignore.internal.Strings.stripTrailing;
import static org.eclipse.jgit.ignore.internal.Strings.stripTrailingWhitespace;

import org.eclipse.jgit.errors.InvalidPatternException;
import org.eclipse.jgit.ignore.internal.IMatcher;
import org.eclipse.jgit.ignore.internal.PathMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * "Fast" (compared with IgnoreRule) git ignore rule implementation supporting
 * also double star <code>**<code> pattern.
 * <p>
 * This class is immutable and thread safe.
 *
 * @since 3.6
 */
public class FastIgnoreRule {
	private final static Logger LOG = LoggerFactory
			.getLogger(FastIgnoreRule.class);

	/**
	 * Character used as default path separator for ignore entries
	 */
	public static final char PATH_SEPARATOR = '/';

	private final IMatcher matcher;

	private final boolean inverse;

	private final boolean dirOnly;

	/**
	 *
	 * @param pattern
	 *            ignore pattern as described in <a href=
	 *            "https://www.kernel.org/pub/software/scm/git/docs/gitignore.html"
	 *            >git manual</a>. If pattern is invalid or is not a pattern
	 *            (comment), this rule doesn't match anything.
	 */
	public FastIgnoreRule(String pattern) {
		if (pattern == null)
			throw new IllegalArgumentException("Pattern must not be null!"); //$NON-NLS-1$
		if (pattern.length() == 0) {
			dirOnly = false;
			inverse = false;
			this.matcher = NO_MATCH;
			return;
		}
		inverse = pattern.charAt(0) == '!';
		if (inverse) {
			pattern = pattern.substring(1);
			if (pattern.length() == 0) {
				dirOnly = false;
				this.matcher = NO_MATCH;
				return;
			}
		}
		if (pattern.charAt(0) == '#') {
			this.matcher = NO_MATCH;
			dirOnly = false;
			return;
		}
		if (pattern.charAt(0) == '\\' && pattern.length() > 1) {
			char next = pattern.charAt(1);
			if (next == '!' || next == '#') {
				// remove backslash escaping first special characters
				pattern = pattern.substring(1);
			}
		}
		dirOnly = isDirectoryPattern(pattern);
		if (dirOnly) {
			pattern = stripTrailingWhitespace(pattern);
			pattern = stripTrailing(pattern, PATH_SEPARATOR);
			if (pattern.length() == 0) {
				this.matcher = NO_MATCH;
				return;
			}
		}
		IMatcher m;
		try {
			m = PathMatcher.createPathMatcher(pattern,
					Character.valueOf(PATH_SEPARATOR), dirOnly);
		} catch (InvalidPatternException e) {
			m = NO_MATCH;
			LOG.error(e.getMessage(), e);
		}
		this.matcher = m;
	}

	/**
	 * Returns true if a match was made. <br>
	 * This function does NOT return the actual ignore status of the target!
	 * Please consult {@link #getResult()} for the negation status. The actual
	 * ignore status may be true or false depending on whether this rule is an
	 * ignore rule or a negation rule.
	 *
	 * @param path
	 *            Name pattern of the file, relative to the base directory of
	 *            this rule
	 * @param directory
	 *            Whether the target file is a directory or not
	 * @return True if a match was made. This does not necessarily mean that the
	 *         target is ignored. Call {@link #getResult() getResult()} for the
	 *         result.
	 */
	public boolean isMatch(String path, boolean directory) {
		if (path == null)
			return false;
		if (path.length() == 0)
			return false;
		boolean match = matcher.matches(path, directory);
		return match;
	}

	/**
	 * @return True if the pattern is just a file name and not a path
	 */
	public boolean getNameOnly() {
		return !(matcher instanceof PathMatcher);
	}

	/**
	 *
	 * @return True if the pattern should match directories only
	 */
	public boolean dirOnly() {
		return dirOnly;
	}

	/**
	 * Indicates whether the rule is non-negation or negation.
	 *
	 * @return True if the pattern had a "!" in front of it
	 */
	public boolean getNegation() {
		return inverse;
	}

	/**
	 * Indicates whether the rule is non-negation or negation.
	 *
	 * @return True if the target is to be ignored, false otherwise.
	 */
	public boolean getResult() {
		return !inverse;
	}

	/**
	 * @return true if the rule never matches (comment line or broken pattern)
	 * @since 4.1
	 */
	public boolean isEmpty() {
		return matcher == NO_MATCH;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		if (inverse)
			sb.append('!');
		sb.append(matcher);
		if (dirOnly)
			sb.append(PATH_SEPARATOR);
		return sb.toString();

	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + (inverse ? 1231 : 1237);
		result = prime * result + (dirOnly ? 1231 : 1237);
		result = prime * result + ((matcher == null) ? 0 : matcher.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!(obj instanceof FastIgnoreRule))
			return false;

		FastIgnoreRule other = (FastIgnoreRule) obj;
		if (inverse != other.inverse)
			return false;
		if (dirOnly != other.dirOnly)
			return false;
		return matcher.equals(other.matcher);
	}
}
