(*********************************************************************************)
(*                OCaml-IRI                                                      *)
(*                                                                               *)
(*    Copyright (C) 2016 Institut National de Recherche en Informatique          *)
(*    et en Automatique. All rights reserved.                                    *)
(*                                                                               *)
(*    This program is free software; you can redistribute it and/or modify       *)
(*    it under the terms of the GNU Lesser General Public License version        *)
(*    3 as published by the Free Software Foundation.                            *)
(*                                                                               *)
(*    This program is distributed in the hope that it will be useful,            *)
(*    but WITHOUT ANY WARRANTY; without even the implied warranty of             *)
(*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *)
(*    GNU Library General Public License for more details.                       *)
(*                                                                               *)
(*    You should have received a copy of the GNU Lesser General Public           *)
(*    License along with this program; if not, write to the Free Software        *)
(*    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                   *)
(*    02111-1307  USA                                                            *)
(*                                                                               *)
(*    Contact: Maxence.Guesdon@inria.fr                                          *)
(*                                                                               *)
(*                                                                               *)
(*********************************************************************************)

type error
exception Error of error

val string_of_error : error -> string

module KV : Map.S with type key = string
type query_kv = string KV.t

type path =
| Absolute of string list
| Relative of string list

type t

(** Empty IRI: all components are empty. *)
val empty : t

(** Parameter [query] is %-encoded.
    Parameter [query_kv] is %-decoded. *)
val iri :
  ?scheme:string ->
  ?user:string ->
  ?host:string ->
  ?port:int ->
  ?path:path ->
  ?query_kv:query_kv ->
  ?query:string -> ?fragment:string -> unit -> t

module Set : Set.S with type elt = t
module Map : Map.S with type key = t

(** [true] if fragment is None and scheme is not empty. *)
val is_absolute : t -> bool

(** [true] is scheme is empty. *)
val is_relative : t -> bool

(** IRI comparison. Optional parameter [normalize] indicates whether to normalize
  the IRIs to compare (default is [false]). *)
val compare : ?normalize:bool -> t -> t -> int

(** Equality. Optional parameter [normalize] indicates whether to normalize
  the IRIs to compare (default is [false]). *)
val equal : ?normalize:bool -> t -> t -> bool

(** Read an IRI from the given string.
  Optional parameter [normalize] tells whether to normalize to IRI or not;
  default is [false] when IRI is relative (has no scheme) or [true] overwise.
  Optional parameter [pctdecode] tells whether to %-decode strings or not;
  default is [true].*)
val of_string : ?pctdecode: bool ->
  ?pos: Lexing.position -> ?normalize:bool -> string -> t

(** Return a string representation of the given IRI.
  Optional parameter [pctencode] is [true] by default. *)
val to_string : ?pctencode: bool -> t -> string

(** Return a debug purpose string representation of the given IRI. *)
val to_string_details : t -> string

(** Print the given IRI to the given formatter, using
  [to_string ?pctencode:None]. *)
val pp : Format.formatter -> t -> unit

(** Print a debug purpose representation of the given IRI
   to the given formatter, using [to_string_details]. *)
val pp_details : Format.formatter -> t  -> unit

val scheme : t -> string
val with_scheme : t -> string -> t

val user : t -> string option
val with_user : t -> string option -> t

val host : t -> string option
val with_host : t -> string option -> t

val port : t -> int option
val with_port : t -> int option -> t

val path : t -> path
val with_path : t -> path -> t

(** Return the path of the given IRI as a string.
  Optional parameter [encode] indicates whether the path elements
  must be encoded; default is [false]. *)
val path_string : ?pctencode: bool -> t -> string

(** Append the given (not %-encoded) string list to the path of the
     given IRI and return a new IRI with this path. *)
val append_path : t -> string list -> t

(** Return the query string of the given IRI. The query string is not %-decoded
  as it is not parsed to name/value pairs. *)
val query : t -> string option

(** Return the key/value pairs from the query string of the given IRI. Strings are %-decoded. *)
val query_kv : t -> query_kv

(** Return a new IRI which is the same as the given IRI but with the
  optional query string provided. This string must already be %-encoded. *)
val with_query : t -> string option -> t

(** [with_query_kv iri kv] returns a new IRI which is the same as the given [iri]
  but with the provided list of key/value pairs [kv]. The strings in [kv] must be %-decoded.
*)
val with_query_kv : t -> query_kv -> t

val query_get : t -> string -> string
val query_opt : t -> string -> string option
val query_set : t -> string -> string -> t

val fragment : t -> string option
val with_fragment : t -> string option -> t

val normalize: ?nfkc:bool -> t -> t

(** [resolve ~base iri] resolves [iri] against the [base] IRI.
  Optional parameter [normalize] tells whether to apply normalization after resolution;
  default is [true]. *)
val resolve : ?normalize: bool -> base: t -> t -> t

val parse_http_link : string -> (string * t) list

(** Return a correctly pct-encoded URI as a string, from the given IRI. *)
val to_uri : t -> string
