// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//


/// A structure designed to parse URLs based on RFC 3986 and to construct URLs from their constituent parts.
///
/// Its behavior differs subtly from the `URL` struct, which conforms to older RFCs. However, you can easily obtain a `URL` based on the contents of a `URLComponents` or vice versa.
public struct URLComponents : ReferenceConvertible, Hashable, Equatable, _MutableBoxing {
    public typealias ReferenceType = NSURLComponents
    
    internal var _handle: _MutableHandle<NSURLComponents>
    
    /// Initialize with all components undefined.
    public init() {
        _handle = _MutableHandle(adoptingReference: NSURLComponents())
    }
    
    /// Initialize with the components of a URL.
    ///
    /// If resolvingAgainstBaseURL is `true` and url is a relative URL, the components of url.absoluteURL are used. If the url string from the URL is malformed, nil is returned.
    public init?(url: URL, resolvingAgainstBaseURL resolve: Bool) {
        guard let result = NSURLComponents(url: url, resolvingAgainstBaseURL: resolve) else { return nil }
        _handle = _MutableHandle(adoptingReference: result)
    }
    
    /// Initialize with a URL string.
    ///
    /// If the URLString is malformed, nil is returned.
    public init?(string: String) {
        guard let result = NSURLComponents(string: string) else { return nil }
        _handle = _MutableHandle(adoptingReference: result)
    }
    
    /// Returns a URL created from the URLComponents.
    ///
    /// If the URLComponents has an authority component (user, password, host or port) and a path component, then the path must either begin with "/" or be an empty string. If the URLComponents does not have an authority component (user, password, host or port) and has a path component, the path component must not start with "//". If those requirements are not met, nil is returned.
    public var url: URL? {
        return _handle.map { $0.url }
    }
    
    /// Returns a URL created from the URLComponents relative to a base URL.
    ///
    /// If the URLComponents has an authority component (user, password, host or port) and a path component, then the path must either begin with "/" or be an empty string. If the URLComponents does not have an authority component (user, password, host or port) and has a path component, the path component must not start with "//". If those requirements are not met, nil is returned.
    public func url(relativeTo base: URL?) -> URL? {
        return _handle.map { $0.url(relativeTo: base) }
    }
    
    // Returns a URL string created from the URLComponents. If the URLComponents has an authority component (user, password, host or port) and a path component, then the path must either begin with "/" or be an empty string. If the URLComponents does not have an authority component (user, password, host or port) and has a path component, the path component must not start with "//". If those requirements are not met, nil is returned.
    public var string: String? {
        return _handle.map { $0.string }
    }
    
    /// The scheme subcomponent of the URL.
    ///
    /// The getter for this property removes any percent encoding this component may have (if the component allows percent encoding). Setting this property assumes the subcomponent or component string is not percent encoded and will add percent encoding (if the component allows percent encoding).
    /// Attempting to set the scheme with an invalid scheme string will cause an exception.
    public var scheme: String? {
        get { return _handle.map { $0.scheme } }
        set { _applyMutation { $0.scheme = newValue } }
    }
    
    /// The user subcomponent of the URL.
    ///
    /// The getter for this property removes any percent encoding this component may have (if the component allows percent encoding). Setting this property assumes the subcomponent or component string is not percent encoded and will add percent encoding (if the component allows percent encoding).
    ///
    /// Warning: IETF STD 66 (rfc3986) says the use of the format "user:password" in the userinfo subcomponent of a URI is deprecated because passing authentication information in clear text has proven to be a security risk. However, there are cases where this practice is still needed, and so the user and password components and methods are provided.
    public var user: String? {
        get { return _handle.map { $0.user } }
        set { _applyMutation { $0.user = newValue } }
    }
    
    /// The password subcomponent of the URL.
    ///
    /// The getter for this property removes any percent encoding this component may have (if the component allows percent encoding). Setting this property assumes the subcomponent or component string is not percent encoded and will add percent encoding (if the component allows percent encoding).
    ///
    /// Warning: IETF STD 66 (rfc3986) says the use of the format "user:password" in the userinfo subcomponent of a URI is deprecated because passing authentication information in clear text has proven to be a security risk. However, there are cases where this practice is still needed, and so the user and password components and methods are provided.
    public var password: String? {
        get { return _handle.map { $0.password } }
        set { _applyMutation { $0.password = newValue } }
    }
    
    /// The host subcomponent.
    ///
    /// The getter for this property removes any percent encoding this component may have (if the component allows percent encoding). Setting this property assumes the subcomponent or component string is not percent encoded and will add percent encoding (if the component allows percent encoding).
    public var host: String? {
        get { return _handle.map { $0.host } }
        set { _applyMutation { $0.host = newValue } }
    }
    
    /// The port subcomponent.
    ///
    /// The getter for this property removes any percent encoding this component may have (if the component allows percent encoding). Setting this property assumes the subcomponent or component string is not percent encoded and will add percent encoding (if the component allows percent encoding).
    /// Attempting to set a negative port number will cause a fatal error.
    public var port: Int? {
        get { return _handle.map { $0.port?.intValue } }
        set { _applyMutation { $0.port = newValue != nil ? NSNumber(value: newValue!) : nil as NSNumber?} }
    }
    
    /// The path subcomponent.
    ///
    /// The getter for this property removes any percent encoding this component may have (if the component allows percent encoding). Setting this property assumes the subcomponent or component string is not percent encoded and will add percent encoding (if the component allows percent encoding).
    public var path: String {
        get {
            guard let result = _handle.map({ $0.path }) else { return "" }
            return result
        }
        set {
            _applyMutation { $0.path = newValue }
        }
    }
    
    /// The query subcomponent.
    ///
    /// The getter for this property removes any percent encoding this component may have (if the component allows percent encoding). Setting this property assumes the subcomponent or component string is not percent encoded and will add percent encoding (if the component allows percent encoding).
    public var query: String? {
        get { return _handle.map { $0.query } }
        set { _applyMutation { $0.query = newValue } }
    }
    
    /// The fragment subcomponent.
    ///
    /// The getter for this property removes any percent encoding this component may have (if the component allows percent encoding). Setting this property assumes the subcomponent or component string is not percent encoded and will add percent encoding (if the component allows percent encoding).
    public var fragment: String? {
        get { return _handle.map { $0.fragment } }
        set { _applyMutation { $0.fragment = newValue } }
    }
    
    
    /// The user subcomponent, percent-encoded.
    ///
    /// The getter for this property retains any percent encoding this component may have. Setting this properties assumes the component string is already correctly percent encoded. Attempting to set an incorrectly percent encoded string will cause a `fatalError`. Although ';' is a legal path character, it is recommended that it be percent-encoded for best compatibility with `URL` (`String.addingPercentEncoding(withAllowedCharacters:)` will percent-encode any ';' characters if you pass `CharacterSet.urlUserAllowed`).
    public var percentEncodedUser: String? {
        get { return _handle.map { $0.percentEncodedUser } }
        set { _applyMutation { $0.percentEncodedUser = newValue } }
    }
    
    /// The password subcomponent, percent-encoded.
    ///
    /// The getter for this property retains any percent encoding this component may have. Setting this properties assumes the component string is already correctly percent encoded. Attempting to set an incorrectly percent encoded string will cause a `fatalError`. Although ';' is a legal path character, it is recommended that it be percent-encoded for best compatibility with `URL` (`String.addingPercentEncoding(withAllowedCharacters:)` will percent-encode any ';' characters if you pass `CharacterSet.urlPasswordAllowed`).
    public var percentEncodedPassword: String? {
        get { return _handle.map { $0.percentEncodedPassword } }
        set { _applyMutation { $0.percentEncodedPassword = newValue } }
    }
    
    /// The host subcomponent, percent-encoded.
    ///
    /// The getter for this property retains any percent encoding this component may have. Setting this properties assumes the component string is already correctly percent encoded. Attempting to set an incorrectly percent encoded string will cause a `fatalError`. Although ';' is a legal path character, it is recommended that it be percent-encoded for best compatibility with `URL` (`String.addingPercentEncoding(withAllowedCharacters:)` will percent-encode any ';' characters if you pass `CharacterSet.urlHostAllowed`).
    public var percentEncodedHost: String? {
        get { return _handle.map { $0.percentEncodedHost } }
        set { _applyMutation { $0.percentEncodedHost = newValue } }
    }
    
    /// The path subcomponent, percent-encoded.
    ///
    /// The getter for this property retains any percent encoding this component may have. Setting this properties assumes the component string is already correctly percent encoded. Attempting to set an incorrectly percent encoded string will cause a `fatalError`. Although ';' is a legal path character, it is recommended that it be percent-encoded for best compatibility with `URL` (`String.addingPercentEncoding(withAllowedCharacters:)` will percent-encode any ';' characters if you pass `CharacterSet.urlPathAllowed`).
    public var percentEncodedPath: String {
        get {
            guard let result = _handle.map({ $0.percentEncodedPath }) else { return "" }
            return result
        }
        set {
            _applyMutation { $0.percentEncodedPath = newValue }
        }
    }
    
    /// The query subcomponent, percent-encoded.
    ///
    /// The getter for this property retains any percent encoding this component may have. Setting this properties assumes the component string is already correctly percent encoded. Attempting to set an incorrectly percent encoded string will cause a `fatalError`. Although ';' is a legal path character, it is recommended that it be percent-encoded for best compatibility with `URL` (`String.addingPercentEncoding(withAllowedCharacters:)` will percent-encode any ';' characters if you pass `CharacterSet.urlQueryAllowed`).
    public var percentEncodedQuery: String? {
        get { return _handle.map { $0.percentEncodedQuery } }
        set { _applyMutation { $0.percentEncodedQuery = newValue } }
    }
    
    /// The fragment subcomponent, percent-encoded.
    ///
    /// The getter for this property retains any percent encoding this component may have. Setting this properties assumes the component string is already correctly percent encoded. Attempting to set an incorrectly percent encoded string will cause a `fatalError`. Although ';' is a legal path character, it is recommended that it be percent-encoded for best compatibility with `URL` (`String.addingPercentEncoding(withAllowedCharacters:)` will percent-encode any ';' characters if you pass `CharacterSet.urlFragmentAllowed`).
    public var percentEncodedFragment: String? {
        get { return _handle.map { $0.percentEncodedFragment } }
        set { _applyMutation { $0.percentEncodedFragment = newValue } }
    }
    
    private func _toStringRange(_ r : NSRange) -> Range<String.Index>? {
        guard r.location != NSNotFound else { return nil }
        
        let utf16Start = String.UTF16View.Index(encodedOffset: r.location)
        let utf16End = String.UTF16View.Index(encodedOffset: r.location + r.length)
        
        guard let s = self.string else { return nil }
        guard let start = String.Index(utf16Start, within: s) else { return nil }
        guard let end = String.Index(utf16End, within: s) else { return nil }
        
        return start..<end
    }
    
    /// Returns the character range of the scheme in the string returned by `var string`.
    ///
    /// If the component does not exist, nil is returned.
    /// - note: Zero length components are legal. For example, the URL string "scheme://:@/?#" has a zero length user, password, host, query and fragment; the URL strings "scheme:" and "" both have a zero length path.
    public var rangeOfScheme: Range<String.Index>? {
        return _toStringRange(_handle.map { $0.rangeOfScheme })
    }
    
    /// Returns the character range of the user in the string returned by `var string`.
    ///
    /// If the component does not exist, nil is returned.
    /// - note: Zero length components are legal. For example, the URL string "scheme://:@/?#" has a zero length user, password, host, query and fragment; the URL strings "scheme:" and "" both have a zero length path.
    public var rangeOfUser: Range<String.Index>? {
        return _toStringRange(_handle.map { $0.rangeOfUser})
    }
    
    /// Returns the character range of the password in the string returned by `var string`.
    ///
    /// If the component does not exist, nil is returned.
    /// - note: Zero length components are legal. For example, the URL string "scheme://:@/?#" has a zero length user, password, host, query and fragment; the URL strings "scheme:" and "" both have a zero length path.
    public var rangeOfPassword: Range<String.Index>? {
        return _toStringRange(_handle.map { $0.rangeOfPassword})
    }
    
    /// Returns the character range of the host in the string returned by `var string`.
    ///
    /// If the component does not exist, nil is returned.
    /// - note: Zero length components are legal. For example, the URL string "scheme://:@/?#" has a zero length user, password, host, query and fragment; the URL strings "scheme:" and "" both have a zero length path.
    public var rangeOfHost: Range<String.Index>? {
        return _toStringRange(_handle.map { $0.rangeOfHost})
    }
    
    /// Returns the character range of the port in the string returned by `var string`.
    ///
    /// If the component does not exist, nil is returned.
    /// - note: Zero length components are legal. For example, the URL string "scheme://:@/?#" has a zero length user, password, host, query and fragment; the URL strings "scheme:" and "" both have a zero length path.
    public var rangeOfPort: Range<String.Index>? {
        return _toStringRange(_handle.map { $0.rangeOfPort})
    }
    
    /// Returns the character range of the path in the string returned by `var string`.
    ///
    /// If the component does not exist, nil is returned.
    /// - note: Zero length components are legal. For example, the URL string "scheme://:@/?#" has a zero length user, password, host, query and fragment; the URL strings "scheme:" and "" both have a zero length path.
    public var rangeOfPath: Range<String.Index>? {
        return _toStringRange(_handle.map { $0.rangeOfPath})
    }
    
    /// Returns the character range of the query in the string returned by `var string`.
    ///
    /// If the component does not exist, nil is returned.
    /// - note: Zero length components are legal. For example, the URL string "scheme://:@/?#" has a zero length user, password, host, query and fragment; the URL strings "scheme:" and "" both have a zero length path.
    public var rangeOfQuery: Range<String.Index>? {
        return _toStringRange(_handle.map { $0.rangeOfQuery})
    }
    
    /// Returns the character range of the fragment in the string returned by `var string`.
    ///
    /// If the component does not exist, nil is returned.
    /// - note: Zero length components are legal. For example, the URL string "scheme://:@/?#" has a zero length user, password, host, query and fragment; the URL strings "scheme:" and "" both have a zero length path.
    public var rangeOfFragment: Range<String.Index>? {
        return _toStringRange(_handle.map { $0.rangeOfFragment})
    }
    
    /// Returns an array of query items for this `URLComponents`, in the order in which they appear in the original query string.
    ///
    /// Each `URLQueryItem` represents a single key-value pair,
    ///
    /// Note that a name may appear more than once in a single query string, so the name values are not guaranteed to be unique. If the `URLComponents` has an empty query component, returns an empty array. If the `URLComponents` has no query component, returns nil.
    ///
    /// The setter combines an array containing any number of `URLQueryItem`s, each of which represents a single key-value pair, into a query string and sets the `URLComponents` query property. Passing an empty array sets the query component of the `URLComponents` to an empty string. Passing nil removes the query component of the `URLComponents`.
    ///
    /// - note: If a name-value pair in a query is empty (i.e. the query string starts with '&', ends with '&', or has "&&" within it), you get a `URLQueryItem` with a zero-length name and and a nil value. If a query's name-value pair has nothing before the equals sign, you get a zero-length name. If a query's name-value pair has nothing after the equals sign, you get a zero-length value. If a query's name-value pair has no equals sign, the query name-value pair string is the name and you get a nil value.
    public var queryItems: [URLQueryItem]? {
        get { return _handle.map { $0.queryItems } }
        set { _applyMutation { $0.queryItems = newValue } }
    }
    
    public var hashValue: Int {
        return _handle.map { $0.hash }
    }
    
    // MARK: - Bridging
    
    fileprivate init(reference: NSURLComponents) {
        _handle = _MutableHandle(reference: reference)
    }
    
    public static func ==(lhs: URLComponents, rhs: URLComponents) -> Bool {
        // Don't copy references here; no one should be storing anything
        return lhs._handle._uncopiedReference().isEqual(rhs._handle._uncopiedReference())
    }
}

extension URLComponents : CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
    public var description: String {
        if let u = url {
            return u.description
        } else {
            return self.customMirror.children.reduce("") {
                $0.appending("\($1.label ?? ""): \($1.value) ")
            }
        }
    }
    
    public var debugDescription: String {
        return self.description
    }
    
    public var customMirror: Mirror {
        var c: [(label: String?, value: Any)] = []
        
        if let s = self.scheme { c.append((label: "scheme", value: s)) }
        if let u = self.user { c.append((label: "user", value: u)) }
        if let pw = self.password { c.append((label: "password", value: pw)) }
        if let h = self.host { c.append((label: "host", value: h)) }
        if let p = self.port { c.append((label: "port", value: p)) }
        
        c.append((label: "path", value: self.path))
        if #available(OSX 10.10, iOS 8.0, *) {
            if let qi = self.queryItems { c.append((label: "queryItems", value: qi )) }
        }
        if let f = self.fragment { c.append((label: "fragment", value: f)) }
        let m = Mirror(self, children: c, displayStyle: Mirror.DisplayStyle.struct)
        return m
    }
}

/// A single name-value pair, for use with `URLComponents`.
public struct URLQueryItem : ReferenceConvertible, Hashable, Equatable {
    public typealias ReferenceType = NSURLQueryItem
    
    fileprivate var _queryItem : NSURLQueryItem
    
    public init(name: String, value: String?) {
        _queryItem = NSURLQueryItem(name: name, value: value)
    }
    
    fileprivate init(reference: NSURLQueryItem) { _queryItem = reference.copy() as! NSURLQueryItem }
    fileprivate var reference : NSURLQueryItem { return _queryItem }
    
    public var name: String {
        get { return _queryItem.name }
        set { _queryItem = NSURLQueryItem(name: newValue, value: value) }
    }
    
    public var value: String? {
        get { return _queryItem.value }
        set { _queryItem = NSURLQueryItem(name: name, value: newValue) }
    }
    
    public var hashValue: Int { return _queryItem.hash }
    
    public static func ==(lhs: URLQueryItem, rhs: URLQueryItem) -> Bool {
        return lhs._queryItem.isEqual(rhs._queryItem)
    }
}

extension URLQueryItem : CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
    public var description: String {
        if let v = value {
            return "\(name)=\(v)"
        } else {
            return name
        }
    }
    
    public var debugDescription: String {
        return self.description
    }

    public var customMirror: Mirror {
        var c: [(label: String?, value: Any)] = []
        c.append((label: "name", value: name))
        c.append((label: "value", value: value as Any))
        return Mirror(self, children: c, displayStyle: Mirror.DisplayStyle.struct)
    }
}

extension NSURLComponents : _SwiftBridgeable {
    typealias SwiftType = URLComponents
    internal var _swiftObject: SwiftType { return URLComponents(reference: self) }
}

extension URLComponents : _NSBridgeable {
    typealias NSType = NSURLComponents
    internal var _nsObject: NSType { return _handle._copiedReference() }
}

extension NSURLQueryItem : _SwiftBridgeable {
    typealias SwiftType = URLQueryItem
    internal var _swiftObject: SwiftType { return URLQueryItem(reference: self) }
}

extension URLQueryItem : _NSBridgeable {
    typealias NSType = NSURLQueryItem
    internal var _nsObject: NSType { return _queryItem }
}

extension URLComponents : _ObjectTypeBridgeable {
    public typealias _ObjectType = NSURLComponents
    
    public static func _getObjectiveCType() -> Any.Type {
        return NSURLComponents.self
    }
    
    @_semantics("convertToObjectiveC")
    public func _bridgeToObjectiveC() -> NSURLComponents {
        return _handle._copiedReference()
    }
    
    public static func _forceBridgeFromObjectiveC(_ x: NSURLComponents, result: inout URLComponents?) {
        if !_conditionallyBridgeFromObjectiveC(x, result: &result) {
            fatalError("Unable to bridge \(_ObjectType.self) to \(self)")
        }
    }
    
    public static func _conditionallyBridgeFromObjectiveC(_ x: NSURLComponents, result: inout URLComponents?) -> Bool {
        result = URLComponents(reference: x)
        return true
    }
    
    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSURLComponents?) -> URLComponents {
        var result: URLComponents? = nil
        _forceBridgeFromObjectiveC(source!, result: &result)
        return result!
    }
}

extension URLQueryItem : _ObjectTypeBridgeable {
    public typealias _ObjectType = NSURLQueryItem
    
    public static func _getObjectiveCType() -> Any.Type {
        return NSURLQueryItem.self
    }
    
    @_semantics("convertToObjectiveC")
    public func _bridgeToObjectiveC() -> NSURLQueryItem {
        return _queryItem
    }
    
    public static func _forceBridgeFromObjectiveC(_ x: NSURLQueryItem, result: inout URLQueryItem?) {
        if !_conditionallyBridgeFromObjectiveC(x, result: &result) {
            fatalError("Unable to bridge \(_ObjectType.self) to \(self)")
        }
    }
    
    public static func _conditionallyBridgeFromObjectiveC(_ x: NSURLQueryItem, result: inout URLQueryItem?) -> Bool {
        result = URLQueryItem(reference: x)
        return true
    }
    
    public static func _unconditionallyBridgeFromObjectiveC(_ source: NSURLQueryItem?) -> URLQueryItem {
        var result: URLQueryItem? = nil
        _forceBridgeFromObjectiveC(source!, result: &result)
        return result!
    }
}
