// 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 NSURLComponents.
    ///
    /// If the NSURLComponents 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 NSURLComponents 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 NSURLComponents relative to a base URL.
    ///
    /// If the NSURLComponents 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 NSURLComponents 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 NSURLComponents. If the NSURLComponents 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 NSURLComponents 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(_offset: r.location)
        let utf16End = String.UTF16View.Index(_offset: 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?.map { return $0 as URLQueryItem } } }
        set { _applyMutation { $0.queryItems = newValue?.map { $0 } } }
    }
    
    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!
    }
}
