// ***************************************************************************************************************************
// * 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.internal.StringUtils.*;

import org.apache.juneau.annotation.*;
import org.apache.juneau.json.*;
import org.apache.juneau.parser.*;

/**
 * Represents a URL broken into authority/context-root/servlet-path/path-info parts.
 *
 * <p>
 * A typical request against a URL takes the following form:
 * <p class='bcode w800'>
 * 	http://host:port/context-root/servlet-path/path-info
 * 	|   authority   |  context   |  resource  |  path  |
 * 	+--------------------------------------------------+
 * </p>
 *
 * <p>
 * This class allows you to convert URL strings to absolute (e.g. <js>"http://host:port/foo/bar"</js>) or root-relative
 * (e.g. <js>"/foo/bar"</js>) URLs.
 */
@Bean
public class UriContext {

	/**
	 * Default URI context.
	 *
	 * <p>
	 * No information about authority, servlet-root, context-root, or path-info is known.
	 */
	public static final UriContext DEFAULT = new UriContext();

	@SuppressWarnings("javadoc")
	public final String authority, contextRoot, servletPath, pathInfo, parentPath;

	// Lazy-initialized fields.
	private String aContextRoot, rContextRoot, aServletPath, rResource, aPathInfo, rPath;

	/**
	 * Constructor.
	 *
	 * <p>
	 * Leading and trailing slashes are trimmed of all parameters.
	 *
	 * <p>
	 * Any parameter can be <jk>null</jk>.  Blanks and nulls are equivalent.
	 *
	 * @param authority
	 * 	The authority portion of URL (e.g. <js>"http://hostname:port"</js>)
	 * @param contextRoot
	 * 	The context root of the application (e.g. <js>"/context-root"</js>, or <js>"context-root"</js>)
	 * @param servletPath
	 * 	The servlet path (e.g. <js>"/servlet-path"</js>, or <js>"servlet-path"</js>)
	 * @param pathInfo
	 * 	The path info (e.g. <js>"/path-info"</js>, or <js>"path-info"</js>)
	 */
	@Beanc
	public UriContext(@Name("authority") String authority, @Name("contextRoot") String contextRoot, @Name("servletPath") String servletPath, @Name("pathInfo") String pathInfo) {
		this.authority = nullIfEmpty(trimSlashes(authority));
		this.contextRoot = nullIfEmpty(trimSlashes(contextRoot));
		this.servletPath = nullIfEmpty(trimSlashes(servletPath));
		this.pathInfo = nullIfEmpty(trimSlashes(pathInfo));
		this.parentPath = this.pathInfo == null || this.pathInfo.indexOf('/') == -1 ? null
			: this.pathInfo.substring(0, this.pathInfo.lastIndexOf('/'));
	}

	/**
	 * Default constructor.
	 *
	 * <p>
	 * All <jk>null</jk> values.
	 */
	public UriContext() {
		this(null, null, null, null);
	}

	/**
	 * String constructor.
	 *
	 * <p>
	 * Input string is a JSON object with the following format:
	 * <js>{authority:'xxx',contextRoot:'xxx',servletPath:'xxx',pathInfo:'xxx'}</js>
	 *
	 * @param s
	 * 	The input string.
	 * 	<br>Example: <js>{authority:'http://localhost:10000',contextRoot:'/myContext',servletPath:'/myServlet',pathInfo:'/foo'}</js>
	 * @throws ParseException
	 * 	If input string is not a valid JSON object.
	 */
	public UriContext(String s) throws ParseException {
		ObjectMap m = new ObjectMap(s);
		this.authority = nullIfEmpty(trimSlashes(m.getString("authority")));
		this.contextRoot = nullIfEmpty(trimSlashes(m.getString("contextRoot")));
		this.servletPath = nullIfEmpty(trimSlashes(m.getString("servletPath")));
		this.pathInfo = nullIfEmpty(trimSlashes(m.getString("pathInfo")));
		this.parentPath = this.pathInfo == null || this.pathInfo.indexOf('/') == -1 ? null
			: this.pathInfo.substring(0, this.pathInfo.lastIndexOf('/'));
	}

	/**
	 * Returns the absolute URI of just the authority portion of this URI context.
	 *
	 * <p>
	 * Example:  <js>"http://hostname:port"</js>
	 *
	 * <p>
	 * If the authority is null/empty, returns <js>"/"</js>.
	 *
	 * @return
	 * 	The absolute URI of just the authority portion of this URI context.
	 * 	Never <jk>null</jk>.
	 */
	public String getAbsoluteAuthority() {
		return authority == null ? "/" : authority;
	}

	/**
	 * Returns the absolute URI of the context-root portion of this URI context.
	 *
	 * <p>
	 * Example:  <js>"http://hostname:port/context-root"</js>
	 *
	 * @return
	 * 	The absolute URI of the context-root portion of this URI context.
	 * 	Never <jk>null</jk>.
	 */
	public String getAbsoluteContextRoot() {
		if (aContextRoot == null) {
			if (authority == null)
				aContextRoot = getRootRelativeContextRoot();
			else
				aContextRoot = (
					contextRoot == null
					? authority
					: (authority + '/' + contextRoot)
				);
		}
		return aContextRoot;
	}

	/**
	 * Returns the root-relative URI of the context portion of this URI context.
	 *
	 * <p>
	 * Example:  <js>"/context-root"</js>
	 *
	 * @return
	 * 	The root-relative URI of the context portion of this URI context.
	 * 	Never <jk>null</jk>.
	 */
	public String getRootRelativeContextRoot() {
		if (rContextRoot == null)
			rContextRoot = contextRoot == null ? "/" : ('/' + contextRoot);
		return rContextRoot;
	}

	/**
	 * Returns the absolute URI of the resource portion of this URI context.
	 *
	 * <p>
	 * Example:  <js>"http://hostname:port/context-root/servlet-path"</js>
	 *
	 * @return
	 * 	The absolute URI of the resource portion of this URI context.
	 * 	Never <jk>null</jk>.
	 */
	public String getAbsoluteServletPath() {
		if (aServletPath == null) {
			if (authority == null)
				aServletPath = getRootRelativeServletPath();
			else {
				if (contextRoot == null)
					aServletPath = (
						servletPath == null
						? authority
						: authority + '/' + servletPath
					);
				else
					aServletPath = (
						servletPath == null
						? (authority + '/' + contextRoot)
						: (authority + '/' + contextRoot + '/' + servletPath)
					);
			}
		}
		return aServletPath;
	}

	/**
	 * Returns the root-relative URI of the resource portion of this URI context.
	 *
	 * <p>
	 * Example:  <js>"/context-root/servlet-path"</js>
	 *
	 * @return
	 * 	The root-relative URI of the resource portion of this URI context.
	 * 	Never <jk>null</jk>.
	 */
	public String getRootRelativeServletPath() {
		if (rResource == null) {
			if (contextRoot == null)
				rResource = (
					servletPath == null
					? "/"
					: ('/' + servletPath)
				);
			else
				rResource = (
					servletPath == null
					? ('/' + contextRoot)
					: ('/' + contextRoot + '/' + servletPath)
				);
		}
		return rResource;
	}

	/**
	 * Returns the parent of the URL returned by {@link #getAbsoluteServletPath()}.
	 *
	 * @return The parent of the URL returned by {@link #getAbsoluteServletPath()}.
	 */
	public String getAbsoluteServletPathParent() {
		return getParent(getAbsoluteServletPath());
	}

	/**
	 * Returns the parent of the URL returned by {@link #getRootRelativeServletPath()}.
	 *
	 * @return The parent of the URL returned by {@link #getRootRelativeServletPath()}.
	 */
	public String getRootRelativeServletPathParent() {
		return getParent(getRootRelativeServletPath());
	}

	/**
	 * Returns the absolute URI of the path portion of this URI context.
	 *
	 * <p>
	 * Example:  <js>"http://hostname:port/context-root/servlet-path/path-info"</js>
	 *
	 * @return
	 * 	The absolute URI of the path portion of this URI context.
	 * 	Never <jk>null</jk>.
	 */
	public String getAbsolutePathInfo() {
		if (aPathInfo == null) {
			if (authority == null)
				aPathInfo = getRootRelativePathInfo();
			else {
				if (contextRoot == null) {
					if (servletPath == null)
						aPathInfo = (
							pathInfo == null
							? authority : (authority + '/' + pathInfo)
						);
					else
						aPathInfo = (
							pathInfo == null
							? (authority + '/' + servletPath)
							: (authority + '/' + servletPath + '/' + pathInfo)
						);
				} else {
					if (servletPath == null)
						aPathInfo = (
							pathInfo == null
							? authority + '/' + contextRoot
							: (authority + '/' + contextRoot + '/' + pathInfo)
						);
					else
						aPathInfo = (
							pathInfo == null
							? (authority + '/' + contextRoot + '/' + servletPath)
							: (authority + '/' + contextRoot + '/' + servletPath + '/' + pathInfo)
						);
				}
			}
		}
		return aPathInfo;
	}

	/**
	 * Returns the root-relative URI of the path portion of this URI context.
	 *
	 * <p>
	 * Example:  <js>"/context-root/servlet-path/path-info"</js>
	 *
	 * @return
	 * 	The root-relative URI of the path portion of this URI context.
	 * 	Never <jk>null</jk>.
	 */
	public String getRootRelativePathInfo() {
		if (rPath == null) {
			if (contextRoot == null) {
				if (servletPath == null)
					rPath = (
						pathInfo == null
						? "/"
						: ('/' + pathInfo)
					);
				else
					rPath = (
						pathInfo == null
						? ('/' + servletPath)
						: ('/' + servletPath + '/' + pathInfo)
					);
			} else {
				if (servletPath == null)
					rPath = (
						pathInfo == null
						? ('/' + contextRoot)
						: ('/' + contextRoot + '/' + pathInfo)
					);
				else
					rPath = (
						pathInfo == null
						? ('/' + contextRoot + '/' + servletPath)
						: ('/' + contextRoot + '/' + servletPath + '/' + pathInfo)
					);
			}
		}
		return rPath;
	}

	/**
	 * Returns the parent of the URL returned by {@link #getAbsolutePathInfo()}.
	 *
	 * @return The parent of the URL returned by {@link #getAbsolutePathInfo()}.
	 */
	public String getAbsolutePathInfoParent() {
		return getParent(getAbsolutePathInfo());
	}

	/**
	 * Returns the parent of the URL returned by {@link #getRootRelativePathInfo()}.
	 *
	 * @return The parent of the URL returned by {@link #getRootRelativePathInfo()}.
	 */
	public String getRootRelativePathInfoParent() {
		return getParent(getRootRelativePathInfo());
	}

	private static String getParent(String uri) {
		int i = uri.lastIndexOf('/');
		if (i <= 1)
			return "/";
		return uri.substring(0, i);
	}

	@Override /* Object */
	public String toString() {
		return SimpleJsonSerializer.DEFAULT.toString(this);
	}
}
