/*
 * 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.
 */

#ifndef _DECAF_NET_URI_H_
#define _DECAF_NET_URI_H_

#include <decaf/util/Config.h>
#include <decaf/lang/Comparable.h>
#include <decaf/lang/exceptions/IllegalArgumentException.h>
#include <decaf/net/URISyntaxException.h>
#include <decaf/net/MalformedURLException.h>
#include <decaf/net/URL.h>
#include <string>
#include <apr_uri.h>
#include <decaf/internal/AprPool.h>

namespace decaf{
namespace net{

    /**
     * This class represents an instance of a URI as defined by RFC 2396.
     */
    class DECAF_API URI : public lang::Comparable<URI> {
    private:

        // Apr Data for parsing the uri.
        apr_uri_t uri;
        internal::AprPool pool;

        // The original string entered from URI( string ), empty if not set.
        const char* uriString;

        static const std::string unreserved;
        static const std::string punct;
        static const std::string reserved;
        static const std::string someLegal;
        static const std::string allLegal;

    public:

        /**
         * Constructs a URI from the given string
         * @param uri - string uri to parse.
         */
        URI( const std::string& uri ) throw ( URISyntaxException );

        /**
         * Constructs a URI from the given components.
         * @param scheme - the uri scheme
         * @param ssp - Scheme specific part
         * @param fragment - Fragment
         */
        URI( const std::string& scheme,
             const std::string& ssp,
             const std::string& fragment) throw ( URISyntaxException );

        /**
         * Constructs a URI from the given components.
         * @param scheme - Scheme name
         * @param userInfo - User name and authorization information
         * @param host - Host name
         * @param port - Port number
         * @param path - Path
         * @param query - Query
         * @param fragment - Fragment
         */
        URI( const std::string& scheme, const std::string& userInfo,
             const std::string& host, int port,
             const std::string& path, const std::string& query,
             const std::string& fragment ) throw ( URISyntaxException );

        /**
         * Constructs a URI from the given components.
         * @param scheme - Scheme name
         * @param host - Host name
         * @param path - Path
         * @param fragment - Fragment
         */
        URI( const std::string& scheme, const std::string& host,
             const std::string& path, const std::string& fragment )
                 throw ( URISyntaxException );

        /**
         * Constructs a URI from the given components.
         * @param scheme - Scheme name
         * @param authority - Authority
         * @param path - Path
         * @param query - Query
         * @param fragment - Fragment
         */
        URI( const std::string& scheme, const std::string& authority,
             const std::string& path, const std::string& query,
             const std::string& fragment ) throw ( URISyntaxException);

        virtual ~URI() {}

        /**
         * Compares this object with the specified object for order. Returns a
         * negative integer, zero, or a positive integer as this object is less
         * than, equal to, or greater than the specified object.
         * @param value - the value to compare to this one.
         * @returns zero if equal minus one if less than and one if greater than.
         */
        virtual int compareTo( const URI& value ) const;

        /**
         * @return true if this value is considered equal to the passed value.
         */
        virtual bool equals( const URI& value ) const;

        /**
         * Compares equality between this object and the one passed.
         * @param value - the value to be compared to this one.
         * @return true if this object is equal to the one passed.
         */
        virtual bool operator==( const URI& value ) const;

        /**
         * Compares this object to another and returns true if this object
         * is considered to be less than the one passed.  This
         * @param value - the value to be compared to this one.
         * @return true if this object is equal to the one passed.
         */
        virtual bool operator<( const URI& value ) const;

        /**
         * @eturns the decoded authority component of this URI.
         */
        std::string getAuthority() const;

        /**
         * @returns the decoded fragment component of this URI.
         */
        std::string getFragment() const;

        /**
         * @returns the host component of this URI.
         */
        std::string getHost() const;

        /**
         * @returns the path component of this URI.
         */
        std::string getPath() const;

        /**
         * @returns the port component of this URI.
         */
        int getPort() const;

        /**
         * @returns the query component of this URI.
         */
        std::string getQuery() const;

        /**
         * @returns the scheme component of this URI
         */
        std::string getScheme() const;

        /**
         * @returns the user info component of this URI
         */
        std::string getUserInfo() const;

        /**
         * Returns the raw authority component of this URI.
         *
         * The authority component of a URI, if defined, only contains the
         * commercial-at character ('@') and characters in the unreserved, punct,
         * escaped, and other categories. If the authority is server-based then
         * it is further constrained to have valid user-information, host, and
         * port components.
         * @returns the raw authority component of the URI
         */
        std::string getRawAuthority() const;

        /**
         * Returns the raw fragment component of this URI.
         *
         * The fragment component of a URI, if defined, only contains legal URI
         * characters.
         * @returns the raw fragment component of this URI
         */
        std::string getRawFragment() const;

        /**
         * Returns the raw path component of this URI.
         *
         * The path component of a URI, if defined, only contains the slash
         * character ('/'), the commercial-at character ('@'), and characters
         * in the unreserved, punct, escaped, and other categories.
         * @returns the raw path component of this URI
         */
        std::string getRawPath() const;

        /**
         * Returns the raw query component of this URI.
         * The query component of a URI, if defined, only contains legal URI characters.
         * @returns the raw query component of the URI.
         */
        std::string getRawQuery() const;

        /**
         * Returns the raw scheme-specific part of this URI. The scheme-specific
         * part is never undefined, though it may be empty.
         * The scheme-specific part of a URI only contains legal URI characters.
         * @returns the raw scheme special part of the uri
         */
        std::string getRawSchemeSpecificPart() const;

        /**
         * Returns the decoded scheme-specific part of this URI.
         * The string returned by this method is equal to that returned by the
         * getRawSchemeSpecificPart method except that all sequences of escaped
         * octets are decoded.
         * @returns the raw scheme specific part of the uri.
         */
        std::string getSchemeSpecificPart() const;

        /**
         * Returns the raw user-information component of this URI.
         * The user-information component of a URI, if defined, only contains
         * characters in the unreserved, punct, escaped, and other categories.
         * @returns the raw user-information component of the URI
         */
        std::string getRawUserInfo() const;

        /**
         * Tells whether or not this URI is absolute.  A URI is absolute if,
         * and only if, it has a scheme component.
         * @returns true if, and only if, this URI is absolute
         */
        bool isAbsolute() const;

        /**
         * Tells whether or not this URI is opaque.  A URI is opaque if, and only
         * if, it is absolute and its scheme-specific part does not begin with a
         * slash character ('/'). An opaque URI has a scheme, a scheme-specific
         * part, and possibly a fragment; all other components are undefined.
         * @returns true if, and only if, this URI is opaque
         */
        bool isOpaque() const;

        /**
         * Normalizes this URI's path.  If this URI is opaque, or if its path is
         * already in normal form, then this URI is returned. Otherwise a new URI
         * is constructed that is identical to this URI except that its path is
         * computed by normalizing this URI's path in a manner consistent with
         * RFC 2396, section 5.2, step 6, sub-steps c through f; that is:
         *
         *  1. All "." segments are removed.
         *  2. If a ".." segment is preceded by a non-".." segment then both of t
         *     hese segments are removed. This step is repeated until it is no
         *     longer applicable.
         *  3. If the path is relative, and if its first segment contains a colon
         *     character (':'), then a "." segment is prepended. This prevents a
         *     relative URI with a path such as "a:b/c/d" from later being re-parsed
         *     as an opaque URI with a scheme of "a" and a scheme-specific part of
         *     "b/c/d". (Deviation from RFC 2396)
         *
         * A normalized path will begin with one or more ".." segments if there were
         * insufficient non-".." segments preceding them to allow their removal. A
         * normalized path will begin with a "." segment if one was inserted by step
         * 3 above. Otherwise, a normalized path will not contain any "." or ".."
         * segments.
         * @returns A URI equivalent to this URI, but whose path is in normal form
         */
        URI normalize() const;

        /**
         * Attempts to parse this URI's authority component, if defined, into
         * user-information, host, and port components.
         *
         * If this URI's authority component has already been recognized as being
         * server-based then it will already have been parsed into user-information,
         * host, and port components. In this case, or if this URI has no authority
         * component, this method simply returns this URI.
         *
         * Otherwise this method attempts once more to parse the authority component
         * into user-information, host, and port components, and throws an exception
         * describing why the authority component could not be parsed in that way.
         * @returns A URI whose authority field has been parsed as a server-based
         * authority
         * @throws URISyntaxException - If the authority component of this URI is
         * defined but cannot be parsed as a server-based authority.
         */
        URI parseServerAuthority() const throw ( URISyntaxException );

        /**
         * Relativizes the given URI against this URI.  The relativization of the
         * given URI against this URI is computed as follows:
         *
         *  1. If either this URI or the given URI are opaque, or if the scheme and
         *     authority components of the two URIs are not identical, or if the path
         *     of this URI is not a prefix of the path of the given URI, then the
         *     given URI is returned.
         *  2. Otherwise a new relative hierarchical URI is constructed with query
         *     and fragment components taken from the given URI and with a path
         *     component computed by removing this URI's path from the beginning of
         *     the given URI's path.
         *
         * @param uri - The URI to be relativized against this URI
         * @returns The resulting URI
         */
        URI relativize( const URI& uri ) const;

        /**
         * Constructs a new URI by parsing the given string and then resolving it
         * against this URI.
         *
         * This convenience method works as if invoking it were equivalent to
         * evaluating the expression resolve( URI::create( str ) ).
         * @param str - The string to be parsed into a URI
         * @returns The resulting URI
         * @throws IllegalArgumentException - If the given string violates RFC 2396
         */
        URI resolve( const std::string& str )
            throw ( lang::exceptions::IllegalArgumentException );

        /**
         * Resolves the given URI against this URI.
         *
         * If the given URI is already absolute, or if this URI is opaque, then a
         * copy of the given URI is returned.
         *
         * If the given URI's fragment component is defined, its path component is
         * empty, and its scheme, authority, and query components are undefined, then
         * a URI with the given fragment but with all other components equal to those
         * of this URI is returned. This allows a URI representing a standalone
         * fragment reference, such as "#foo", to be usefully resolved against a base
         * URI.
         *
         * Otherwise this method constructs a new hierarchical URI in a manner
         * consistent with RFC 2396, section 5.2; that is:
         *
         *  1. A new URI is constructed with this URI's scheme and the given URI's
         *     query and fragment components.
         *  2. If the given URI has an authority component then the new URI's authority
         *     and path are taken from the given URI.
         *  3. Otherwise the new URI's authority component is copied from this URI,
         *     and its path is computed as follows:
         *
         *     1. If the given URI's path is absolute then the new URI's path is
         *        taken from the given URI.
         *     2. Otherwise the given URI's path is relative, and so the new URI's
         *        path is computed by resolving the path of the given URI against the
         *        path of this URI. This is done by concatenating all but the last
         *        segment of this URI's path, if any, with the given URI's path and
         *        then normalizing the result as if by invoking the normalize method.
         *
         * The result of this method is absolute if, and only if, either this URI is
         * absolute or the given URI is absolute.
         * @param uri - The URI to be resolved against this URI
         * @returns The resulting URI
         */
        URI resolve( const URI& uri );

        /**
         * Returns the content of this URI as a string.
         *
         * If this URI was created by invoking one of the constructors in this class
         * then a string equivalent to the original input string, or to the string
         * computed from the originally-given components, as appropriate, is returned.
         * Otherwise this URI was created by normalization, resolution, or
         * relativization, and so a string is constructed from this URI's components
         * according to the rules specified in RFC 2396, section 5.2, step 7.
         * @returns the string form of this URI
         */
        std::string toString() const;

        /**
         * Constructs a URL from this URI.
         *
         * This convenience method works as if invoking it were equivalent to
         * evaluating the expression new URL(this.toString()) after first checking
         * that this URI is absolute.
         * @returns A URL constructed from this URI
         * @throws IllegalArgumentException - If this URL is not absolute
         * @throws MalformedURLException - If a protocol handler for the URL could not
         * be found, or if some other error occurred while constructing the URL
         */
        URL toURL() const
            throw ( MalformedURLException, lang::exceptions::IllegalArgumentException );

    public:   // Static Methods

        /**
         * Creates a URI by parsing the given string.
         * This convenience factory method works as if by invoking the URI(string)
         * constructor; any URISyntaxException thrown by the constructor is caught
         * and wrapped in a new IllegalArgumentException object, which is then thrown.
         * @param uri - URI string to parse
         * @throws IllegalArgumentException
         */
        static URI create( const std::string uri )
            throw ( lang::exceptions::IllegalArgumentException );

    private:

        // Parses a URI string and fills in the member data, throws a
        // URISyntaxException if things fail
        void parseURI( const std::string& uri ) throw ( URISyntaxException );

        /*
         * Quote illegal chars for each component, but not the others
         *
         * @param component java.lang.String the component to be converted @param
         * legalset java.lang.String the legal character set allowed in the
         * component s @return java.lang.String the converted string
         */
        std::string quoteComponent( const std::string& component,
                                    const std::string& legalset );

    };

}}

#endif /*_DECAF_NET_URI_H_*/
