// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau;

import static org.apache.juneau.UriRelativity.*;
import static org.apache.juneau.UriResolution.*;
import static org.apache.juneau.internal.StringUtils.*;

import java.io.*;
import java.net.*;

/**
 * Class used to create absolute and root-relative URIs based on your current URI 'location' and rules about how to
 * make such resolutions.
 *
 * <p>
 * Combines a {@link UriContext} instance with rules for resolution ({@link UriResolution} and relativity
 * ({@link UriRelativity}) to define simple {@link #resolve(Object)} and {@link #append(Appendable, Object)} methods.
 *
 * <p>
 * Three special protocols are used to represent context-root-relative, servlet-relative, and request-path-relative
 * URIs:
 * 	<js>"context:/"</js>, <js>"servlet:/"</js>, and <js>"request:/"</js>.
 *
 * <p>
 * The following list shows the protocols of URLs that can be resolved with this class:
 * <ul>
 * 	<li><js>"foo://foo"</js> - Absolute URI.
 * 	<li><js>"/foo"</js> - Root-relative URI.
 * 	<li><js>"/"</js> - Root URI.
 * 	<li><js>"context:/foo"</js> - Context-root-relative URI.
 * 	<li><js>"context:/"</js> - Context-root URI.
 * 	<li><js>"servlet:/foo"</js> - Servlet-path-relative URI.
 * 	<li><js>"servlet:/"</js> - Servlet-path URI.
 * 	<li><js>"request:/foo"</js> - Request-path-relative URI.
 * 	<li><js>"request:/"</js> - Request-path URI.
 * 	<li><js>"foo"</js> - Path-info-relative URI.
 * 	<li><js>""</js> - Path-info URI.
 * </ul>
*/
public class UriResolver {

	private final UriResolution resolution;
	private final UriRelativity relativity;
	private final String authority, contextRoot, servletPath, pathInfo, parentPath;

	/**
	 * Constructor.
	 *
	 * @param resolution Rule on how URIs should be resolved.
	 * @param relativity Rule on what relative URIs are relative to.
	 * @param uriContext Current URI context (i.e. the current URI 'location').
	 */
	public UriResolver(UriResolution resolution, UriRelativity relativity, UriContext uriContext) {
		this.resolution = resolution;
		this.relativity = relativity;
		this.authority = uriContext.authority;
		this.contextRoot = uriContext.contextRoot;
		this.servletPath = uriContext.servletPath;
		this.pathInfo = uriContext.pathInfo;
		this.parentPath = uriContext.parentPath;
	}

	/**
	 * Converts the specified URI to absolute form based on values in this context.
	 *
	 * @param uri
	 * 	The URI to convert to absolute form.
	 * 	Can be any of the following:
	 * 	<ul>
	 * 		<li>{@link java.net.URI}
	 * 		<li>{@link java.net.URL}
	 * 		<li>{@link CharSequence}
	 * 	</ul>
	 * 	URI can be any of the following forms:
	 * 	<ul>
	 * 		<li><js>"foo://foo"</js> - Absolute URI.
	 * 		<li><js>"/foo"</js> - Root-relative URI.
	 * 		<li><js>"/"</js> - Root URI.
	 * 		<li><js>"context:/foo"</js> - Context-root-relative URI.
	 * 		<li><js>"context:/"</js> - Context-root URI.
	 * 		<li><js>"servlet:/foo"</js> - Servlet-path-relative URI.
	 * 		<li><js>"servlet:/"</js> - Servlet-path URI.
	 * 		<li><js>"request:/foo"</js> - Request-path-relative URI.
	 * 		<li><js>"request:/"</js> - Request-path URI.
	 * 		<li><js>"foo"</js> - Path-info-relative URI.
	 * 		<li><js>""</js> - Path-info URI.
	 * 	</ul>
	 * @return The converted URI.
	 */
	public String resolve(Object uri) {
		return resolve(uri, resolution);
	}

	private String resolve(Object uri, UriResolution res) {
		String s = asString(uri);
		if (isAbsoluteUri(s))
			return hasDotSegments(s) && res != NONE ? normalize(s) : s;
		if (res == ROOT_RELATIVE && startsWith(s, '/'))
			return hasDotSegments(s) ? normalize(s) : s;
		if (res == NONE && ! isSpecialUri(s))
			return s;
		return append(new StringBuilder(), s).toString();
	}

	/**
	 * Relativizes a URI.
	 *
	 * <p>
	 * Similar to {@link URI#relativize(URI)}, except supports special protocols (e.g. <js>"servlet:/"</js>) for both
	 * the <code>relativeTo</code> and <code>uri</code> parameters.
	 *
	 * <p>
	 * For example, to relativize a URI to its servlet-relative form:
	 * <p class='bcode w800'>
	 * 	<jc>// relativeUri == "path/foo"</jc>
	 * 	String relativeUri = resolver.relativize(<js>"servlet:/"</js>, <js>"/context/servlet/path/foo"</js>);
	 * </p>
	 *
	 * @param relativeTo The URI to relativize against.
	 * @param uri The URI to relativize.
	 * @return The relativized URI.
	 */
	public String relativize(Object relativeTo, Object uri) {
		String r = resolve(relativeTo, ABSOLUTE);
		String s = resolve(uri, ABSOLUTE);
		return URI.create(r).relativize(URI.create(s)).toString();
	}

	/**
	 * Same as {@link #resolve(Object)} except appends result to the specified appendable.
	 *
	 * @param a The appendable to append the URL to.
	 * @param o The URI to convert to absolute form.
	 * @return The same appendable passed in.
	 */
	public Appendable append(Appendable a, Object o) {

		try {
			String uri = asString(o);
			uri = nullIfEmpty(uri);
			boolean needsNormalize = hasDotSegments(uri) && resolution != null;

			// Absolute paths are not changed.
			if (isAbsoluteUri(uri))
				return a.append(needsNormalize ? normalize(uri) : uri);
			if (resolution == NONE && ! isSpecialUri(uri))
				return a.append(emptyIfNull(uri));
			if (resolution == ROOT_RELATIVE && startsWith(uri, '/'))
				return a.append(needsNormalize ? normalize(uri) : uri);

			Appendable a2 = needsNormalize ? new StringBuilder() : a;

			// Root-relative path
			if (startsWith(uri, '/')) {
				if (authority != null)
					a2.append(authority);
				if (uri.length() != 1)
					a2.append(uri);
				else if (authority == null)
					a2.append('/');
			}

			// Context-relative path
			else if (uri != null && uri.startsWith("context:/")) {
				if (resolution == ABSOLUTE && authority != null)
					a2.append(authority);
				if (contextRoot != null)
					a2.append('/').append(contextRoot);
				if (uri.length() > 9)
					a2.append('/').append(uri.substring(9));
				else if (contextRoot == null && (authority == null || resolution != ABSOLUTE))
					a2.append('/');
			}

			// Resource-relative path
			else if (uri != null && uri.startsWith("servlet:/")) {
				if (resolution == ABSOLUTE && authority != null)
					a2.append(authority);
				if (contextRoot != null)
					a2.append('/').append(contextRoot);
				if (servletPath != null)
					a2.append('/').append(servletPath);
				if (uri.length() > 9)
					a2.append('/').append(uri.substring(9));
				else if (servletPath == null && contextRoot == null && (authority == null || resolution != ABSOLUTE))
					a2.append('/');
			}

			// Request-relative path
			else if (uri != null && uri.startsWith("request:/")) {
				if (resolution == ABSOLUTE && authority != null)
					a2.append(authority);
				if (contextRoot != null)
					a2.append('/').append(contextRoot);
				if (servletPath != null)
					a2.append('/').append(servletPath);
				if (pathInfo != null)
					a2.append('/').append(pathInfo);
				if (uri.length() > 9)
					a2.append('/').append(uri.substring(9));
				else if (servletPath == null && contextRoot == null && pathInfo == null && (authority == null || resolution != ABSOLUTE))
					a2.append('/');
			}

			// Relative path
			else {
				if (resolution == ABSOLUTE && authority != null)
					a2.append(authority);
				if (contextRoot != null)
					a2.append('/').append(contextRoot);
				if (servletPath != null)
					a2.append('/').append(servletPath);
				if (relativity == RESOURCE && uri != null)
					a2.append('/').append(uri);
				else if (relativity == PATH_INFO) {
					if (uri == null) {
						if (pathInfo != null)
							a2.append('/').append(pathInfo);
					} else {
						if (parentPath != null)
							a2.append('/').append(parentPath);
						a2.append('/').append(uri);
					}
				}
				else if (uri == null && contextRoot == null && servletPath == null && (authority == null || resolution != ABSOLUTE))
					a2.append('/');
			}

			if (needsNormalize)
				a.append(normalize(a2.toString()));

			return a;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	private static boolean isSpecialUri(String s) {
		if (s == null || s.length() == 0)
			return false;
		char c = s.charAt(0);
		if (c != 's' && c != 'c' && c != 'r')
			return false;
		return s.startsWith("servlet:/") || s.startsWith("context:/") || s.startsWith("request:/");
	}

	private static String normalize(String s) {
		s = URI.create(s).normalize().toString();
		if (s.length() > 1 && s.charAt(s.length()-1) == '/')
			s = s.substring(0, s.length()-1);
		return s;
	}

	private static boolean hasDotSegments(String s) {
		if (s == null)
			return false;
		for (int i = 0; i < s.length()-1; i++) {
			char c = s.charAt(i);
			if (i == 0 && c == '/')
				return true;
			if (c == '/' && s.charAt(i+1) == '.')
				return true;
		}
		return false;
	}
}
