/*
 * Copyright 2019 Haiku, Inc. All rights reserved.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 *      Nabanita Dash, dashnabanita@gmail.com
 *
 * Proofreaders:
 *      Adrien Destugues, pulkomandy@gmail.com
 *
 * Corresponds to:
 *		headers/os/support/Url.h	 hrev52332
 *		src/kits/support/Url.cpp	 hrev52332
 */

/*!
	\file Url.h
	\ingroup support
	\ingroup libbe
	\brief Provides the BUrl class
	\since Haiku R1
*/

/*!
	\class BUrl
	\ingroup support
	\ingroup libbe
	\brief Represents and manipulates an URL (Uniform Resource Locator).
	\since Haiku R1

	An "Uniform Resource Locator" identifies a place where a resource can
	be found. It specifies both a location and a mechanism to retrieve the
	data. For example, http://www.example.com/index.html indicates a protocol
	(http), a hostname (www.example.com), and a file name (index.html).

	Every URL consists of a sequence of up to five components:
	protocol, authority (consisting of login and password, hostname and port)
	path, request and fragment.

	The format is provided in RFC3986 (URI generic syntax), Appendix B as a regular expression:
	^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?

	This regular expression makes it possible to parse any string as an URL (if there are no
	special characters to spearate the fields, everything will end up in the path compopent).
	However, some characters are not allowed: space, newlines, tabs, <, > and ". If any of these
	is present in the URL string, the parsing results in an empty URL.

	The protocols (http, https, ftp, irc, etc) identifies which way the resource
	can be accessed.

	Authority consists of userinfo such as username and password, a host
	subcomponent consisting of IP address or hostname and a port subcomponent.

	The path component locates the resource inside the authority's hierarchy,
	and can have different formats (for example, directory names separated by
	slashes) depending on the protocol in use.

	The request component (preceeded by a question mark) contains a query
	string of non-hierarchial data.

	The fragment contains a fragment identifier providing direction to a
	secondary resource, usually an identifier for a specific element into the
	resource such as a paragraph in a text.
*/

//! @{

/*!
	\fn BUrl::BUrl(const char* url, bool encode = true);
	\brief Constructs a BUrl and fills it.

	\param url A string to parse and populate the URL fields from.
	\param encode Wether to urlencode the string.

	The URL fields are extracted from the passed string and encoded. If you are constructing an
	URL from a string that is already URL-encoded, set encode to false.

	Call InitCheck() to verify that the string was succesfully parsed and
	resulted in a valid URL.
*/

/*!
	\fn BUrl::BUrl(BMessage* archive);
	\brief Restore an URL from archived data.

	\param archive An archived BUrl (using BArchive()).

	Usually, archived messages are restored using BArchivable::Unarchive()
	which will automatically instanciate the correct class.
*/

/*!
	\fn BUrl::BUrl(const BUrl& other);
	\brief Copy constructor

	\param other A BUrl object to copy.
*/

/*!
	\fn BUrl::BUrl(const BUrl& base, const BString& relative);
	\brief Construct a BUrl using a known base and a string representing a relative URL.

	\param base A BUrl object that holds base URL.
	\param relative A path relative to the base URL.

	URLs can sometimes be represented in relative form. For example, links in
	a webpage may refer to only a path, assuming the same protocol and authority
	are the same as the current page. This constructor applies the required
	resolution process to construct a complete, standalone URL from such a
	string.

	For example, the following:

	BUrl base("http://example.org/path/page.html");
	BUrl relative(base, "sudirectory/otherpage.html");

	results in:

	"http://example.org/path/subdirectory/otherpage.hhtml"

	The relative URL can override any of the fields from the original one. The algorithm
	for resolution is documented in RFC3986 section 5.
*/

/*!
	\fn BUrl::BUrl(const BPath& path);
	\brief Constructs a BUrl identifying a local file.

	\param path The path to convert into an URL

	The generated URL uses the file protocol, and its path component is the
	path given as a parameter.
*/

/*!
	\fn BUrl::BUrl();
	\brief Constructs an empty BUrl.
*/

/*!
	\fn BUrl::~BUrl();
	\brief Destructor for BUrl.
*/

//! @}

//! @{

/*!
	\fn BUrl& BUrl::SetUrlString(const BString& url, bool encode = true);
	\brief Parse a string and set the URL accordingly

	\param url A string to parse as an absolute URL.
	\param encode Wether to URL-encode the string.

	Set encode to false if the URL string is already URL-encoded.
*/

/*!
	\fn BUrl& BUrl::SetProtocol(const BString& scheme);
	\brief Set the protocol

	\param scheme The protocol to use.
*/

/*!
	\fn BUrl& BUrl::SetUserName(const BString& user);
	\brief Set the username in the authority component

	\param user The username.
*/

/*!
	\fn BUrl& BUrl::SetPassword(const BString& password);
	\brief Set the password in the authority component

	\param password The password.
*/

/*!
	\fn void BUrl::SetAuthority(const BString& authority);
	\brief Replace the complete authority component

	\param authority The authority component.

	The username, password, host and port fields are replaced. The authority
	can be of the form username:password\@host:port
*/

/*!
	\fn BUrl& BUrl::SetHost(const BString& host);
	\brief Sets the host part of the authority component.

	\param host The hostname or address to use.
*/

/*!
	\fn BUrl& BUrl::SetPort(int port);
	\brief Set the port of the authority component

	\param port The port number to use (usually a TCP or UDP port).
*/

/*!
	\fn BUrl& BUrl::SetPath(const BString& path);
	\brief Set the path of the URL.

	\param path Set the path to use.
*/

/*!
	\fn BUrl& BUrl::SetRequest(const BString& request);
	\brief Set the request part of the URL.

	\param request The request string.
*/

/*!
	\fn BUrl& BUrl::SetFragment(const BString& fragment);
	\brief Set the fragment part of the URL.

	\param fragment The fragment to use.
*/

//! @}

//! @{

/*!
	\fn const BString& BUrl::UrlString() const;
	\brief Returns the string representation of the URL.

	\returns the string representation of the URL.

	A complete URL string is of the form protocol://username:passord\@host:port/path?request#fragment .
	All the fields are optional, for example a file URL will have only a protocol and a path.
*/

/*!
	\fn const BString& BUrl::Protocol() const;
	\brief Returns the protocol used in the url.

	\returns The URL protocol.
*/

/*!
	\fn const BString& BUrl::UserName() const;
	\brief Returns the username.

	\returns The username.
*/

/*!
	\fn const BString& BUrl::Password() const;
	\brief Returns the password.

	\returns The password.
*/

/*!
	\fn const BString& BUrl::UserInfo() const;
	\brief Returns the user information (username:password)

	\returns The username and password.

	If there is no password, the username alone is returned. If there is no
	username, a string of the form ":password" is returned.
*/

/*!
	\fn const BString& BUrl::Host() const;
	\brief Returns the URL host component.

	\returns The URL host.
*/

/*!
	\fn int BUrl::Port() const;
	\brief Returns the URL port number.

	\returns The URL port number.

	-1 is returned if no port is set.
*/

/*!
	\fn const BString& BUrl::Authority() const;
	\brief Returns the authority url as a string.

	\returns The authority url as a string.

	The authority is of the form username:password\@host:port.
*/

/*!
	\fn const BString& BUrl::Path() const;
	\brief Returns the url path.

	\returns The url-path.
*/

/*!
	\fn const BString& BUrl::Request() const;
	\brief Returns the url-request.

	\returns The url-request as a string.
*/

/*!
	\fn const BString& BUrl::Fragment() const;
	\brief Returns the fragment of the url.

	\returns The fragment of the url as a string.
*/

//! @}

//! @{

/*!
	\fn bool BUrl::IsValid() const;
	\brief Check if the URL is valid.

	\returns true if the URL is valid.

	This function verifies that the mandatory fields are present and perform
	some other sanity checks on the URL.

	An URL is valid if:
	- It has a protocol, starting with an alphabetic character and folowed by alphanumeric or +, -,
	  or . characters exclusively,
	- If the protocol requires one, there is a valid host,
	- If the protocol requires one, there is a path.
	- If there is a host, it is either an IPv4 address or valid DNS name, or an IPv6 address
	  enclosed in brackets

	An invalid URL can still be modified using the various setters to turn it into a valid one.
*/

/*!
	\fn bool BUrl::HasProtocol() const;
	\brief Check wether the URL has a protocol.

	\returns True if the URL has a protocol.
*/

/*!
	\fn bool BUrl::HasUserName() const;
	\brief Check wether the URL has an username.

	\returns True if the URL has an username.
*/

/*!
	\fn bool BUrl::HasPassword() const;
	\brief Check wether the URL has a password.

	\returns True if the URL has a password.
*/

/*!
	\fn bool BUrl::HasUserInfo() const;
	\brief Check wether the URL has user information.

	\returns True if the URL has an username or password.
*/

/*!
	\fn bool BUrl::HasHost() const;
	\brief Check wether the URL has an host.

	\returns True if the URL has an host.
*/

/*!
	\fn bool BUrl::HasPort() const;
	\brief Check wether the URL has a port.

	\returns True if the URL has a port.
*/

/*!
	\fn bool BUrl::HasAuthority() const;
	\brief Check if the URL has an host or port.

	\returns True if the URL has an host or port.
*/

/*!
	\fn bool BUrl::HasPath() const;
	\brief Check wether the URL has a path.

	\returns True if the URL has a path.
*/

/*!
	\fn bool BUrl::HasRequest() const;
	\brief Check wether the URL has a request.

	\returns True if the URL has a request.
*/

/*!
	\fn bool BUrl::HasFragment() const;
	\brief Check wether the URL has a fragment.

	\returns True if the URL has a fragment.
*/

//! @}


/*!
	\fn static BString BUrl::UrlEncode(const BString& url, bool strict=false, bool directory=false)
	\brief URL-encode a string containing an URL or URL component.

	\param strict Use strict mode
	\param directory Use directory mode

	In strict mode, space are replaced by %20. In non-strict mode they are replaced by a +
	character.

	In directory mode, / and \\ characters are not encoded. In the other fields they are
	percent-encoded.

	\return The encoded URL string

	\since Haiku R1
*/


/*!
	\fn static BString BUrl::UrlDecode(const BString& url, bool strict=false)
	\brief URL-decode a string containing an URL or URL component.

	\param strict Use strict mode.

	\return The decoded URL string

	\since Haiku R1
*/


/*!
	\fn status_t BUrl::IDNAToAscii()
	\brief Undocumented public method

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn status_t BUrl::IDNAToUnicode()
	\brief Undocumented public method

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn bool BUrl::HasPreferredApplication() const
	\brief Undocumented public method

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn BString BUrl::PreferredApplication() const
	\brief Undocumented public method

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn status_t BUrl::OpenWithPreferredApplication(bool onProblemAskUser=true) const
	\brief Undocumented public method

	\param onProblemAskUser Undocumented

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn bool BUrl::operator==(BUrl &other) const
	\brief Undocumented public method

	\param other Undocumented

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn bool BUrl::operator!=(BUrl &other) const
	\brief Undocumented public method

	\param other Undocumented

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn const BUrl& BUrl::operator=(const BUrl &other)
	\brief Undocumented public method

	\param other Undocumented

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn const BUrl& BUrl::operator=(const BString &string)
	\brief Undocumented public method

	\param string Undocumented

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn const BUrl& BUrl::operator=(const char *string)
	\brief Undocumented public method

	\param string Undocumented

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn BUrl::operator const char *() const
	\brief Undocumented public method

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/


/*!
	\fn static static BArchivable* BUrl::Instantiate(BMessage *archive)
	\brief Undocumented public method

	\param archive Undocumented

	\return Undocumented
	\retval <value> Undocumented

	\since Haiku R1
*/
