/*******************************************************************************
 * Copyright (c) 2011, 2019 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
 *     Raymond Augé <raymond.auge@liferay.com> - Bug 436698
 *******************************************************************************/
package org.eclipse.equinox.http.servlet.internal.registration;

import java.io.IOException;
import java.util.Arrays;
import java.util.regex.Pattern;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.equinox.http.servlet.internal.context.ContextController;
import org.eclipse.equinox.http.servlet.internal.context.ContextController.ServiceHolder;
import org.eclipse.equinox.http.servlet.internal.servlet.FilterChainImpl;
import org.eclipse.equinox.http.servlet.internal.servlet.Match;
import org.eclipse.equinox.http.servlet.internal.util.Const;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.http.runtime.dto.FilterDTO;

//This class wraps the filter object registered in the HttpService.registerFilter call, to manage the context classloader when handleRequests are being asked.
public class FilterRegistration
	extends MatchableRegistration<Filter, FilterDTO>
	implements Comparable<FilterRegistration> {

	private final ServiceHolder<Filter> filterHolder;
	private final ClassLoader classLoader;
	private final int priority;
	private final ContextController contextController;
	private final boolean initDestoyWithContextController;
	private final Pattern[] compiledRegexs;
	private final boolean needDecode;

	public FilterRegistration(
		ServiceHolder<Filter> filterHolder, FilterDTO filterDTO, int priority,
		ContextController contextController) {

		super(filterHolder.get(), filterDTO);
		this.filterHolder = filterHolder;
		this.priority = priority;
		this.contextController = contextController;
		this.compiledRegexs = getCompiledRegex(filterDTO);
		if (filterHolder.getLegacyTCCL() != null) {
			// legacy filter registrations used the current TCCL at registration time
			classLoader = filterHolder.getLegacyTCCL();
		} else {
			classLoader = filterHolder.getBundle().adapt(BundleWiring.class).getClassLoader();
		}
		initDestoyWithContextController = true;
		needDecode = MatchableRegistration.patternsRequireDecode(filterDTO.patterns);
	}

	public int compareTo(FilterRegistration otherFilterRegistration) {
		int priorityDifference = priority - otherFilterRegistration.priority;
		if (priorityDifference != 0)
			return -priorityDifference;

		// Note that we use abs here because the DTO service ID may have been negated for legacy filters.
		// We always compare with the positive id values and we know the positive values are unique.
		long thisId = Math.abs(getD().serviceId);
		long otherId = Math.abs(otherFilterRegistration.getD().serviceId);
		return (thisId < otherId) ? -1 : ((thisId == otherId) ? 0 : 1);
	}

	public void destroy() {
		if (!initDestoyWithContextController) {
			return;
		}
		ClassLoader original = Thread.currentThread().getContextClassLoader();
		try {
			Thread.currentThread().setContextClassLoader(classLoader);
			contextController.getHttpServiceRuntime().getRegisteredObjects().remove(this.getT());
			contextController.getFilterRegistrations().remove(this);
			contextController.ungetServletContextHelper(filterHolder.getBundle());
			super.destroy();
			getT().destroy();
		}
		finally {
			destroyContextAttributes();
			Thread.currentThread().setContextClassLoader(original);
			filterHolder.release();
		}
	}

	public boolean appliesTo(FilterChainImpl filterChainImpl) {
		return (Arrays.binarySearch(
			getD().dispatcher, filterChainImpl.getDispatcherType().name()) >= 0);
	}

	//Delegate the handling of the request to the actual filter
	public void doFilter(
			HttpServletRequest request, HttpServletResponse response,
			FilterChain chain)
		throws IOException, ServletException {

		ClassLoader original = Thread.currentThread().getContextClassLoader();
		try {
			Thread.currentThread().setContextClassLoader(classLoader);
			getT().doFilter(request, response, chain);
		}
		finally {
			Thread.currentThread().setContextClassLoader(original);
		}
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof FilterRegistration)) {
			return false;
		}

		FilterRegistration filterRegistration = (FilterRegistration)obj;

		return getT().equals(filterRegistration.getT());
	}

	@Override
	public int hashCode() {
		return Long.valueOf(getD().serviceId).hashCode();
	}

	//Delegate the init call to the actual filter
	public void init(FilterConfig filterConfig) throws ServletException {
		if (!initDestoyWithContextController) {
			return;
		}
		boolean initialized = false;
		ClassLoader original = Thread.currentThread().getContextClassLoader();
		try {
			Thread.currentThread().setContextClassLoader(classLoader);

			createContextAttributes();
			getT().init(filterConfig);
			initialized = true;
		}
		finally {
			if (!initialized) {
				destroyContextAttributes();
			}
			Thread.currentThread().setContextClassLoader(original);
		}
	}

	public String match(
		String name, String requestURI, String extension, Match match) {
		if ((name != null) && (getD().servletNames != null)) {
			for (String servletName : getD().servletNames) {
				if (servletName.equals(name)) {
					return name;
				}
			}
		}

		if (requestURI == null || requestURI.isEmpty()) {
			return null;
		}

		for (String pattern : getD().patterns) {
			if (doPatternMatch(pattern, requestURI, extension)) {
				return pattern;
			}
		}

		for (Pattern regex : compiledRegexs) {
			if (regex.matcher(requestURI).matches()) {
				return regex.toString();
			}
		}

		return null;
	}

	@Override
	public String match(
		String name, String servletPath, String pathInfo, String extension, Match match) {
		// TODO need to rework match for filters to remove this method
		throw new UnsupportedOperationException("Should not be calling this method on FilterRegistration"); //$NON-NLS-1$
	}

	private void createContextAttributes() {
		contextController.getProxyContext().createContextAttributes(
			contextController);
	}

	private void destroyContextAttributes() {
		contextController.getProxyContext().destroyContextAttributes(
			contextController);
	}

	protected boolean isPathWildcardMatch(String pattern, String path) {
		if (path == null) {
			return false;
		}
		// first try wild card matching if the pattern requests it
		if (pattern.endsWith("/*")) { //$NON-NLS-1$
			int pathPatternLength = pattern.length() - 2;
			if (path.regionMatches(0, pattern, 0, pathPatternLength)) {
				return path.length() <= pathPatternLength || path.charAt(pathPatternLength) == '/';
			}
			return false;
		}
		// now do exact matching
		return pattern.equals(path);
	}

	protected boolean doPatternMatch(String pattern, String path, String extension)
		throws IllegalArgumentException {

		if (pattern.indexOf(Const.SLASH_STAR_DOT) == 0) {
			pattern = pattern.substring(1);
		}
		int extensionMatchIndex = pattern.indexOf(Const.SLASH_STAR_DOT);
		String extensionWithPrefixMatch = null;
		if (extensionMatchIndex >= 0 && pattern.lastIndexOf('/') == extensionMatchIndex) {
			extensionWithPrefixMatch = pattern.substring(extensionMatchIndex + 3);
			pattern = pattern.substring(0, extensionMatchIndex + 2);
		}

		if (pattern.isEmpty() && Const.SLASH.equals(path)) {
			return true;
		}
		else if (!pattern.isEmpty()) {
			// first try prefix path matching; taking into account wild cards if necessary
			if (pattern.charAt(0) == '/') {
				if (isPathWildcardMatch(pattern, path)) {
					if (extensionWithPrefixMatch != null) {
						return extensionWithPrefixMatch.equals(extension);
					}
					// special case for context path
					if (Const.SLASH.equals(path) && Const.SLASH_STAR.equals(pattern)) {
						return false;
					}
					return true;
				}
				return false;
			}

			// next try extension matching if requested
			if (pattern.charAt(0) == '*') {
				return pattern.substring(2).equals(extension);
			}
		}

		return false;
	}

	private Pattern[] getCompiledRegex(FilterDTO filterDTO) {
		if (filterDTO.regexs == null) {
			return new Pattern[0];
		}

		Pattern[] patterns = new Pattern[filterDTO.regexs.length];

		for (int i = 0; i < filterDTO.regexs.length; i++) {
			patterns[i] = Pattern.compile(filterDTO.regexs[i]);
		}

		return patterns;
	}

	@Override
	public boolean needDecode() {
		return needDecode;
	}

}
