/*
 * The contents of this file are subject to the terms
 * of the Common Development and Distribution License
 * (the "License").  You may not use this file except
 * in compliance with the License.
 * 
 * You can obtain a copy of the license at
 * http://www.opensource.org/licenses/cddl1.php
 * See the License for the specific language governing
 * permissions and limitations under the License.
 */

/*
 * UriBuilder.java
 *
 * Created on July 18, 2007, 11:53 AM
 *
 */

package javax.ws.rs.core;

import java.lang.reflect.Method;
import java.net.URI;
import java.util.Map;
import javax.ws.rs.ext.RuntimeDelegate;

/**
 * URI template aware utility class for building URIs from their components. See
 * {@link javax.ws.rs.Path#value} for an explanation of URI templates.
 * 
 * <p>Builder methods perform contextual encoding of characters not permitted in
 * the corresponding URI component following the rules of the 
 * <a href="http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1">application/x-www-form-urlencoded</a>
 * media type for query parameters and
 * <a href="http://ietf.org/rfc/rfc3986.txt">RFC 3986</a> for all other
 * components. Note that only characters not permitted in a particular component
 * are subject to encoding so, e.g., a path supplied to one of the {@code path}
 * methods may contain matrix parameters or multiple path segments since the
 * separators are legal characters and will not be encoded. Percent encoded 
 * values are also recognized where allowed and will not be double encoded.</p>
 * 
 * <p>URI templates are allowed in most components of a URI but their value is
 * restricted to a particular component. E.g. 
 * <blockquote><code>UriBuilder.fromPath("{arg1}").build("foo#bar");</code></blockquote>
 * would result in encoding of the '#' such that the resulting URI is 
 * "foo%23bar". To create a URI "foo#bar" use
 * <blockquote><code>UriBuilder.fromPath("{arg1}").fragment("{arg2}").build("foo", "bar")</code></blockquote>
 * instead. URI template names and delimiters are never encoded but their 
 * values are encoded when a URI is built.
 * Template parameter regular expressions are ignored when building a URI, i.e.
 * no validation is performed.
 * 
 * @see java.net.URI
 * @see javax.ws.rs.Path
 */
public abstract class UriBuilder {
    
    /**
     * Protected constructor, use one of the static <code>from<i>XXX</i></code>
     * methods to obtain an instance.
     */
    protected UriBuilder() {}
    
    /**
     * Creates a new instance of UriBuilder.
     * @return a new instance of UriBuilder
     */
    protected static UriBuilder newInstance() {
        UriBuilder b = RuntimeDelegate.getInstance().createUriBuilder();
        return b;
    }
    
    /**
     * Create a new instance initialized from an existing URI.
     * @param uri a URI that will be used to initialize the UriBuilder.
     * @return a new UriBuilder
     * @throws IllegalArgumentException if uri is null
     */
    public static UriBuilder fromUri(URI uri) throws IllegalArgumentException {
        UriBuilder b = newInstance();
        b.uri(uri);
        return b;
    }
    
    /**
     * Create a new instance initialized from an existing URI.
     * @param uri a URI that will be used to initialize the UriBuilder, may not
     * contain URI parameters.
     * @return a new UriBuilder
     * @throws IllegalArgumentException if uri is not a valid URI or is null
     */
    public static UriBuilder fromUri(String uri) throws IllegalArgumentException {
        URI u;
        try {
            u = URI.create(uri);
        } catch (NullPointerException ex) {
            throw new IllegalArgumentException(ex.getMessage(), ex);
        }
        return fromUri(u);
    }
    
    /**
     * Create a new instance representing a relative URI initialized from a
     * URI path.
     * @param path a URI path that will be used to initialize the UriBuilder, 
     * may contain URI template parameters.
     * @return a new UriBuilder
     * @throws IllegalArgumentException if path is null
     */
    public static UriBuilder fromPath(String path) throws IllegalArgumentException {
        UriBuilder b = newInstance();
        b.replacePath(path);
        return b;
    }

    /**
     * Create a new instance representing a relative URI initialized from a 
     * root resource class.
     * 
     * @param resource a root resource whose {@link javax.ws.rs.Path} value will
     * be used to initialize the UriBuilder.
     * @return a new UriBuilder
     * @throws IllegalArgumentException if resource is not annotated with 
     * {@link javax.ws.rs.Path} or resource is null.
     */
    public static UriBuilder fromResource(Class<?> resource) throws IllegalArgumentException {
        UriBuilder b = newInstance();
        b.path(resource);
        return b;
    }
    
    /**
     * Create a copy of the UriBuilder preserving its state. This is a more
     * efficient means of creating a copy than constructing a new UriBuilder
     * from a URI returned by the {@link #build} method.
     * @return a copy of the UriBuilder
     */
    @Override
    public abstract UriBuilder clone();
    
    /**
     * Copies the non-null components of the supplied URI to the UriBuilder replacing
     * any existing values for those components.
     * @param uri the URI to copy components from
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if uri is null
     */
    public abstract UriBuilder uri(URI uri) throws IllegalArgumentException;
    
    /**
     * Set the URI scheme.
     * @param scheme the URI scheme, may contain URI template parameters.
     * A null value will unset the URI scheme.
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if scheme is invalid
     */
    public abstract UriBuilder scheme(String scheme) throws IllegalArgumentException;
    
    /**
     * Set the URI scheme-specific-part (see {@link java.net.URI}). This 
     * method will overwrite any existing
     * values for authority, user-info, host, port and path.
     * @param ssp the URI scheme-specific-part, may contain URI template parameters
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if ssp cannot be parsed or is null
     */
    public abstract UriBuilder schemeSpecificPart(String ssp) throws IllegalArgumentException;
    
    /**
     * Set the URI user-info.
     * @param ui the URI user-info, may contain URI template parameters.
     * A null value will unset userInfo component of the URI.
     * @return the updated UriBuilder
     */
    public abstract UriBuilder userInfo(String ui);
    
    /**
     * Set the URI host.
     * @return the updated UriBuilder
     * @param host the URI host, may contain URI template parameters.
     * A null value will unset the host component of the URI.
     * @throws IllegalArgumentException if host is invalid.
     */
    public abstract UriBuilder host(String host) throws IllegalArgumentException;
    
    /**
     * Set the URI port.
     * @param port the URI port, a value of -1 will unset an explicit port.
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if port is invalid
     */
    public abstract UriBuilder port(int port) throws IllegalArgumentException;
    
    /**
     * Set the URI path. This method will overwrite 
     * any existing path and associated matrix parameters. 
     * Existing '/' characters are preserved thus a single value can 
     * represent multiple URI path segments.
     * @param path the path, may contain URI template parameters.
     * A null value will unset the path component of the URI.
     * @return the updated UriBuilder
     */
    public abstract UriBuilder replacePath(String path);

    /**
     * Append path to the existing path. 
     * When constructing the final path, a '/' separator will be inserted
     * between the existing path and the supplied path if necessary.
     * Existing '/' characters are preserved thus a single value can 
     * represent multiple URI path segments.
     * @param path the path, may contain URI template parameters
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if path is null
     */
    public abstract UriBuilder path(String path) throws IllegalArgumentException;

    /**
     * Append the path from a Path-annotated class to the
     * existing path.
     * When constructing the final path, a '/' separator will be inserted
     * between the existing path and the supplied path if necessary.
     * 
     * @param resource a resource whose {@link javax.ws.rs.Path} value will be 
     * used to obtain the path to append.
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if resource is null, or
     * if resource is not annotated with {@link javax.ws.rs.Path}
     */
    public abstract UriBuilder path(Class resource) throws IllegalArgumentException;
    
    /**
     * Append the path from a Path-annotated method to the
     * existing path.
     * When constructing the final path, a '/' separator will be inserted
     * between the existing path and the supplied path if necessary.
     * This method is a convenience shortcut to <code>path(Method)</code>, it
     * can only be used in cases where there is a single method with the
     * specified name that is annotated with {@link javax.ws.rs.Path}.
     * 
     * @param resource the resource containing the method
     * @param method the name of the method whose {@link javax.ws.rs.Path} value will be 
     * used to obtain the path to append
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if resource or method is null, 
     * or there is more than or less than one variant of the method annotated with 
     * {@link javax.ws.rs.Path}
     */
    public abstract UriBuilder path(Class resource, String method) throws IllegalArgumentException;
    
    /**
     * Append the path from a {@link javax.ws.rs.Path}-annotated method to the
     * existing path.
     * When constructing the final path, a '/' separator will be inserted
     * between the existing path and the supplied path if necessary.
     * 
     * @param method a method whose {@link javax.ws.rs.Path} value will be 
     * used to obtain the path to append to the existing path
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if any element of methods is null or is
     * not annotated with a {@link javax.ws.rs.Path}
     */
    public abstract UriBuilder path(Method method) throws IllegalArgumentException;
    
    /**
     * Append path segments to the existing path.
     * When constructing the final path, a '/' separator will be inserted
     * between the existing path and the first path segment if necessary and 
     * each supplied segment will also be separated by '/'.
     * Existing '/' characters are encoded thus a single value can 
     * only represent a single URI path segment.
     * @param segments the path segment values, each may contain URI template
     * parameters
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if segments or any element of segments
     * is null
     */
    public abstract UriBuilder segment(String... segments) throws IllegalArgumentException;

    /**
     * Set the matrix parameters of the current final segment of the current URI path.
     * This method will overwrite any existing matrix parameters on the current final
     * segment of the current URI path. Note that the matrix parameters
     * are tied to a particular path segment; subsequent addition of path segments
     * will not affect their position in the URI path.
     * @param matrix the matrix parameters, may contain URI template parameters.
     * A null value will remove all matrix parameters of the current final segment
     * of the current URI path.
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if matrix cannot be parsed
     * @see <a href="http://www.w3.org/DesignIssues/MatrixURIs.html">Matrix URIs</a>
     */
    public abstract UriBuilder replaceMatrix(String matrix) throws IllegalArgumentException;

    /**
     * Append a matrix parameter to the existing set of matrix parameters of 
     * the current final segment of the URI path. If multiple values are supplied
     * the parameter will be added once per value. Note that the matrix parameters
     * are tied to a particular path segment; subsequent addition of path segments
     * will not affect their position in the URI path.
     * @param name the matrix parameter name, may contain URI template parameters
     * @param values the matrix parameter value(s), each object will be converted
     * to a {@code String} using its {@code toString()} method. Stringified
     * values may contain URI template parameters.
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if name or value is null
     * @see <a href="http://www.w3.org/DesignIssues/MatrixURIs.html">Matrix URIs</a>
     */
    public abstract UriBuilder matrixParam(String name, Object... values) throws IllegalArgumentException;

    /**
     * Replace the existing value(s) of a matrix parameter on 
     * the current final segment of the URI path. If multiple values are supplied
     * the parameter will be added once per value. Note that the matrix parameters
     * are tied to a particular path segment; subsequent addition of path segments
     * will not affect their position in the URI path.
     * @param name the matrix parameter name, may contain URI template parameters
     * @param values the matrix parameter value(s), each object will be converted
     * to a {@code String} using its {@code toString()} method. Stringified
     * values may contain URI template parameters. If {@code values} is empty 
     * or null then all current values of the parameter are removed.
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if name is null.
     * @see <a href="http://www.w3.org/DesignIssues/MatrixURIs.html">Matrix URIs</a>
     */
    public abstract UriBuilder replaceMatrixParam(String name, Object... values) throws IllegalArgumentException;

    /**
     * Set the URI query string. This method will overwrite any existing query
     * parameters.
     * @param query the URI query string, may contain URI template parameters.
     * A null value will remove all query parameters.
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if query cannot be parsed
     */
    public abstract UriBuilder replaceQuery(String query) throws IllegalArgumentException;

    /**
     * Append a query parameter to the existing set of query parameters. If
     * multiple values are supplied the parameter will be added once per value.
     * @param name the query parameter name, may contain URI template parameters
     * @param values the query parameter value(s), each object will be converted
     * to a {@code String} using its {@code toString()} method. Stringified
     * values may contain URI template parameters.
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if name or value is null
     */
    public abstract UriBuilder queryParam(String name, Object... values) throws IllegalArgumentException;
    
    /**
     * Replace the existing value(s) of a query parameter. If
     * multiple values are supplied the parameter will be added once per value.
     * @param name the query parameter name, may contain URI template parameters
     * @param values the query parameter value(s), each object will be converted
     * to a {@code String} using its {@code toString()} method. Stringified
     * values may contain URI template parameters. If {@code values} is empty
     * or null then all current values of the parameter are removed.
     * @return the updated UriBuilder
     * @throws IllegalArgumentException if name is null
     */
    public abstract UriBuilder replaceQueryParam(String name, Object... values) throws IllegalArgumentException;
    
    /**
     * Set the URI fragment.
     * @param fragment the URI fragment, may contain URI template parameters.
     * A null value will remove any existing fragment.
     * @return the updated UriBuilder
     */
    public abstract UriBuilder fragment(String fragment);
    
    /**
     * Build a URI, any URI template parameters will be replaced by the value in
     * the supplied map. Values are converted to <code>String</code> using
     * their <code>toString</code> method and are then encoded to match the
     * rules of the URI component to which they pertain. The state of the
     * builder is unaffected; this method may be called multiple times on the 
     * same builder instance.
     * @param isEncoded specifies if the supplied values contain percent
     * encoded characters. If false then all '%' characters will be encoded, if
     * true then only % characters that are not followed by two hexadecimal
     * numbers will be encoded.
     * @param values a map of URI template parameter names and values
     * @return the URI built from the UriBuilder
     * @throws IllegalArgumentException if there are any URI template parameters
     * without a supplied value, or if a template parameter value is null.
     * @throws UriBuilderException if a URI cannot be constructed based on the
     * current state of the builder.
     */
    public abstract URI buildFromMap(boolean isEncoded, Map<String, ? extends Object> values) 
            throws IllegalArgumentException, UriBuilderException;
    
    /**
     * Build a URI, using the supplied values in order to replace any URI
     * template parameters. Values are converted to <code>String</code> using
     * their <code>toString</code> method and are then encoded to match the
     * rules of the URI component to which they pertain. All '%' characters
     * in the stringified values will be encoded.
     * The state of the builder is unaffected; this method may be called
     * multiple times on the same builder instance.
     * <p>All instances of the same template parameter
     * will be replaced by the same value that corresponds to the position of the
     * first instance of the template parameter. e.g. the template "{a}/{b}/{a}"
     * with values {"x", "y", "z"} will result in the the URI "x/y/x", <i>not</i>
     * "x/y/z".
     * @param values a list of URI template parameter values
     * @return the URI built from the UriBuilder
     * @throws IllegalArgumentException if there are any URI template parameters
     * without a supplied value, or if a value is null.
     * @throws UriBuilderException if a URI cannot be constructed based on the
     * current state of the builder.
     */
    public abstract URI build(Object... values) 
            throws IllegalArgumentException, UriBuilderException;
    
    /**
     * Build a URI.
     * Any URI templates parameters will be replaced with the supplied values in
     * order. Values are converted to <code>String</code> using
     * their <code>toString</code> method and are then encoded to match the
     * rules of the URI component to which they pertain. All % characters in
     * the stringified values that are not followed by two hexadecimal numbers 
     * will be encoded.
     * The state of the builder is unaffected; this method may be called
     * multiple times on the same builder instance.
     * <p>All instances of the same template parameter
     * will be replaced by the same value that corresponds to the position of the
     * first instance of the template parameter. e.g. the template "{a}/{b}/{a}"
     * with values {"x", "y", "z"} will result in the the URI "x/y/x", <i>not</i>
     * "x/y/z".
     * @param values a list of URI template parameter values
     * @return the URI built from the UriBuilder
     * @throws IllegalArgumentException if there are any URI template parameters
     * without a supplied value, or if a value is null.
     * @throws UriBuilderException if a URI cannot be constructed based on the
     * current state of the builder.
     */
    public abstract URI buildFromEncoded(Object... values) 
            throws IllegalArgumentException, UriBuilderException;
}
