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

public struct HTTPCookiePropertyKey : RawRepresentable, Equatable, Hashable, Comparable {
    public private(set) var rawValue: String
    
    public init(_ rawValue: String) {
        self.rawValue = rawValue
    }
    
    public init(rawValue: String) {
        self.rawValue = rawValue
    }
    
    public var hashValue: Int {
        return self.rawValue.hashValue
    }
    
    public static func ==(_ lhs: HTTPCookiePropertyKey, _ rhs: HTTPCookiePropertyKey) -> Bool {
        return lhs.rawValue == rhs.rawValue
    }
    
    public static func <(_ lhs: HTTPCookiePropertyKey, _ rhs: HTTPCookiePropertyKey) -> Bool {
        return rhs.rawValue == rhs.rawValue
    }
}

extension HTTPCookiePropertyKey {
    /// Key for cookie name
    public static let name = HTTPCookiePropertyKey(rawValue: "Name")

    /// Key for cookie value
    public static let value = HTTPCookiePropertyKey(rawValue: "Value")

    /// Key for cookie origin URL
    public static let originURL = HTTPCookiePropertyKey(rawValue: "OriginURL")

    /// Key for cookie version
    public static let version = HTTPCookiePropertyKey(rawValue: "Version")

    /// Key for cookie domain
    public static let domain = HTTPCookiePropertyKey(rawValue: "Domain")

    /// Key for cookie path
    public static let path = HTTPCookiePropertyKey(rawValue: "Path")

    /// Key for cookie secure flag
    public static let secure = HTTPCookiePropertyKey(rawValue: "Secure")

    /// Key for cookie expiration date
    public static let expires = HTTPCookiePropertyKey(rawValue: "Expires")

    /// Key for cookie comment text
    public static let comment = HTTPCookiePropertyKey(rawValue: "Comment")

    /// Key for cookie comment URL
    public static let commentURL = HTTPCookiePropertyKey(rawValue: "CommentURL")

    /// Key for cookie discard (session-only) flag
    public static let discard = HTTPCookiePropertyKey(rawValue: "Discard")

    /// Key for cookie maximum age (an alternate way of specifying the expiration)
    public static let maximumAge = HTTPCookiePropertyKey(rawValue: "Max-Age")

    /// Key for cookie ports
    public static let port = HTTPCookiePropertyKey(rawValue: "Port")

    // For Cocoa compatibility
    internal static let created = HTTPCookiePropertyKey(rawValue: "Created")
}

/// `NSHTTPCookie` represents an http cookie.
///
/// An `NSHTTPCookie` instance represents a single http cookie. It is
/// an immutable object initialized from a dictionary that contains
/// the various cookie attributes. It has accessors to get the various
/// attributes of a cookie.
open class HTTPCookie : NSObject {

    let _comment: String?
    let _commentURL: URL?
    let _domain: String
    let _expiresDate: Date?
    let _HTTPOnly: Bool
    let _secure: Bool
    let _sessionOnly: Bool
    let _name: String
    let _path: String
    let _portList: [NSNumber]?
    let _value: String
    let _version: Int
    var _properties: [HTTPCookiePropertyKey : Any]

    static let _attributes: [HTTPCookiePropertyKey]
        = [.name, .value, .originURL, .version, .domain,
           .path, .secure, .expires, .comment, .commentURL,
           .discard, .maximumAge, .port]

    /// Initialize a NSHTTPCookie object with a dictionary of parameters
    ///
    /// - Parameter properties: The dictionary of properties to be used to
    /// initialize this cookie.
    ///
    /// Supported dictionary keys and value types for the
    /// given dictionary are as follows.
    ///
    /// All properties can handle an NSString value, but some can also
    /// handle other types.
    ///
    /// <table border=1 cellspacing=2 cellpadding=4>
    /// <tr>
    ///     <th>Property key constant</th>
    ///     <th>Type of value</th>
    ///     <th>Required</th>
    ///     <th>Description</th>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.comment</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>Comment for the cookie. Only valid for version 1 cookies and
    ///     later. Default is nil.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.commentURL</td>
    ///     <td>NSURL or NSString</td>
    ///     <td>NO</td>
    ///     <td>Comment URL for the cookie. Only valid for version 1 cookies
    ///     and later. Default is nil.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.domain</td>
    ///     <td>NSString</td>
    ///     <td>Special, a value for either .originURL or
    ///     HTTPCookiePropertyKey.domain must be specified.</td>
    ///     <td>Domain for the cookie. Inferred from the value for
    ///     HTTPCookiePropertyKey.originURL if not provided.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.discard</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>A string stating whether the cookie should be discarded at
    ///     the end of the session. String value must be either "TRUE" or
    ///     "FALSE". Default is "FALSE", unless this is cookie is version
    ///     1 or greater and a value for HTTPCookiePropertyKey.maximumAge is not
    ///     specified, in which case it is assumed "TRUE".</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.expires</td>
    ///     <td>NSDate or NSString</td>
    ///     <td>NO</td>
    ///     <td>Expiration date for the cookie. Used only for version 0
    ///     cookies. Ignored for version 1 or greater.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.maximumAge</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>A string containing an integer value stating how long in
    ///     seconds the cookie should be kept, at most. Only valid for
    ///     version 1 cookies and later. Default is "0".</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.name</td>
    ///     <td>NSString</td>
    ///     <td>YES</td>
    ///     <td>Name of the cookie</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.originURL</td>
    ///     <td>NSURL or NSString</td>
    ///     <td>Special, a value for either HTTPCookiePropertyKey.originURL or
    ///     HTTPCookiePropertyKey.domain must be specified.</td>
    ///     <td>URL that set this cookie. Used as default for other fields
    ///     as noted.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.path</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>Path for the cookie. Inferred from the value for
    ///     HTTPCookiePropertyKey.originURL if not provided. Default is "/".
    ///     </td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.port</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>comma-separated integer values specifying the ports for the
    ///     cookie. Only valid for version 1 cookies and later. Default is
    ///     empty string ("").</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.secure</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>A string stating whether the cookie should be transmitted
    ///     only over secure channels. String value must be either "TRUE"
    ///     or "FALSE". Default is "FALSE".</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.value</td>
    ///     <td>NSString</td>
    ///     <td>YES</td>
    ///     <td>Value of the cookie</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.version</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>Specifies the version of the cookie. Must be either "0" or
    ///     "1". Default is "0".</td>
    /// </tr>
    /// </table>
    ///
    /// All other keys are ignored.
    ///
    /// - Returns: An initialized `NSHTTPCookie`, or nil if the set of
    /// dictionary keys is invalid, for example because a required key is
    /// missing, or a recognized key maps to an illegal value.
    ///
    /// - Experiment: This is a draft API currently under consideration for official import into Foundation as a suitable alternative
    /// - Note: Since this API is under consideration it may be either removed or revised in the near future
    public init?(properties: [HTTPCookiePropertyKey : Any]) {
        guard
            let path = properties[.path] as? String,
            let name = properties[.name] as? String,
            let value = properties[.value] as? String
        else {
            return nil
        }

        let canonicalDomain: String
        if let domain = properties[.domain] as? String {
            canonicalDomain = domain
        } else if
            let originURL = properties[.originURL] as? URL,
            let host = originURL.host
        {
            canonicalDomain = host
        } else {
            return nil
        }

        _path = path
        _name = name
        _value = value
        _domain = canonicalDomain

        if let
            secureString = properties[.secure] as? String, secureString.characters.count > 0
        {
            _secure = true
        } else {
            _secure = false
        }

        let version: Int
        if let
            versionString = properties[.version] as? String, versionString == "1"
        {
            version = 1
        } else {
            version = 0
        }
        _version = version

        if let portString = properties[.port] as? String, _version == 1 {
            _portList = portString.characters
                .split(separator: ",")
                .flatMap { Int(String($0)) }
                .map { NSNumber(value: $0) }
        } else {
            _portList = nil
        }

        // TODO: factor into a utility function
        if version == 0 {
            let expiresProperty = properties[.expires]
            if let date = expiresProperty as? Date {
                _expiresDate = date
            } else if let dateString = expiresProperty as? String {
                let formatter = DateFormatter()
                formatter.locale = Locale(identifier: "en_US_POSIX")
                formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss O"   // per RFC 6265 '<rfc1123-date, defined in [RFC2616], Section 3.3.1>'
                let timeZone = TimeZone(abbreviation: "GMT")
                formatter.timeZone = timeZone
                _expiresDate = formatter.date(from: dateString)
            } else {
                _expiresDate = nil
            }
        } else if
            let maximumAge = properties[.maximumAge] as? String,
            let secondsFromNow = Int(maximumAge), _version == 1 {
            _expiresDate = Date(timeIntervalSinceNow: Double(secondsFromNow))
        } else {
            _expiresDate = nil
        }

        if let discardString = properties[.discard] as? String {
            _sessionOnly = discardString == "TRUE"
        } else {
            _sessionOnly = properties[.maximumAge] == nil && version >= 1
        }
        if version == 0 {
            _comment = nil
            _commentURL = nil
        } else {
            _comment = properties[.comment] as? String
            if let commentURL = properties[.commentURL] as? URL {
                _commentURL = commentURL
            } else if let commentURL = properties[.commentURL] as? String {
                _commentURL = URL(string: commentURL)
            } else {
                _commentURL = nil
            }
        }
        _HTTPOnly = false


        _properties = [
            .created : Date().timeIntervalSinceReferenceDate, // Cocoa Compatibility
            .discard : _sessionOnly,
            .domain : _domain,
            .name : _name,
            .path : _path,
            .secure : _secure,
            .value : _value,
            .version : _version
        ]
        if let comment = properties[.comment] {
            _properties[.comment] = comment
        }
        if let commentURL = properties[.commentURL] {
            _properties[.commentURL] = commentURL
        }
        if let expires = properties[.expires] {
            _properties[.expires] = expires
        }
        if let maximumAge = properties[.maximumAge] {
            _properties[.maximumAge] = maximumAge
        }
        if let originURL = properties[.originURL] {
            _properties[.originURL] = originURL
        }
        if let _portList = _portList {
            _properties[.port] = _portList
        }
    }

    /// Return a dictionary of header fields that can be used to add the
    /// specified cookies to the request.
    ///
    /// - Parameter cookies: The cookies to turn into request headers.
    /// - Returns: A dictionary where the keys are header field names, and the values
    /// are the corresponding header field values.
    open class func requestHeaderFields(with cookies: [HTTPCookie]) -> [String : String] {
        var cookieString = cookies.reduce("") { (sum, next) -> String in
            return sum + "\(next._name)=\(next._value); "
        }
        //Remove the final trailing semicolon and whitespace
        if ( cookieString.length > 0 ) {
            cookieString.characters.removeLast()
            cookieString.characters.removeLast()
        }
        return ["Cookie": cookieString]
    }

    /// Return an array of cookies parsed from the specified response header fields and URL.
    ///
    /// This method will ignore irrelevant header fields so
    /// you can pass a dictionary containing data other than cookie data.
    /// - Parameter headerFields: The response header fields to check for cookies.
    /// - Parameter URL: The URL that the cookies came from - relevant to how the cookies are interpeted.
    /// - Returns: An array of NSHTTPCookie objects
    open class func cookies(withResponseHeaderFields headerFields: [String : String], forURL url: URL) -> [HTTPCookie] {

        //HTTP Cookie parsing based on RFC 6265: https://tools.ietf.org/html/rfc6265
        //Though RFC6265 suggests that multiple cookies cannot be folded into a single Set-Cookie field, this is
        //pretty common. It also suggests that commas and semicolons among other characters, cannot be a part of 
        // names and values. This implementation takes care of multiple cookies in the same field, however it doesn't   
        //support commas and semicolons in names and values(except for dates)

        guard let cookies: String = headerFields["Set-Cookie"]  else { return [] }

        let nameValuePairs = cookies.components(separatedBy: ";")          //split the name/value and attribute/value pairs
                                .map({$0.trim()})                           //trim whitespaces
                                .map({removeCommaFromDate($0)})     //get rid of commas in dates
                                .flatMap({$0.components(separatedBy: ",")}) //cookie boundaries are marked by commas
                                .map({$0.trim()})                           //trim again
                                .filter({$0.caseInsensitiveCompare("HTTPOnly") != .orderedSame})  //we don't use HTTPOnly, do we?
                                .flatMap({createNameValuePair(pair: $0)})   //create Name and Value properties 

        //mark cookie boundaries in the name-value array
        var cookieIndices = (0..<nameValuePairs.count).filter({nameValuePairs[$0].hasPrefix("Name")})
        cookieIndices.append(nameValuePairs.count)

        //bake the cookies
        var httpCookies: [HTTPCookie] = []
        for i in 0..<cookieIndices.count-1 {
            if let aCookie = createHttpCookie(url: url, pairs: nameValuePairs[cookieIndices[i]..<cookieIndices[i+1]]) {
                httpCookies.append(aCookie)
            }
        }

        return httpCookies
    }

    //Bake a cookie
    private class func createHttpCookie(url: URL, pairs: ArraySlice<String>) -> HTTPCookie? {
        var properties: [HTTPCookiePropertyKey : Any] = [:]
        for pair in pairs {
            let name = pair.components(separatedBy: "=")[0]
            var value = pair.components(separatedBy: "\(name)=")[1]  //a value can have an "="
            if canonicalize(name) == .expires {
                value = value.insertComma(at: 3)    //re-insert the comma
            }
            properties[canonicalize(name)] = value
        }

        //if domain wasn't provided use the URL
        if properties[.domain] == nil {
            properties[.domain] = url.absoluteString
        }

        //the default Path is "/"
        if properties[.path] == nil {
            properties[.path] = "/"
        }

        return HTTPCookie(properties: properties)
    }

    //we pass this to a map()
    private class func removeCommaFromDate(_ value: String) -> String {
        if value.hasPrefix("Expires") || value.hasPrefix("expires")  {
            return value.removeCommas()
        }
        return value
    }

    //These cookie attributes are defined in RFC 6265 and 2965(which is obsolete)
    //HTTPCookie supports these
    private class func isCookieAttribute(_ string: String) -> Bool {
        return _attributes.first(where: {$0.rawValue.caseInsensitiveCompare(string) == .orderedSame}) != nil
    }

    //Cookie attribute names are case-insensitive as per RFC6265: https://tools.ietf.org/html/rfc6265
    //but HTTPCookie needs only the first letter of each attribute in uppercase
    private class func canonicalize(_ name: String) -> HTTPCookiePropertyKey {
        let idx = _attributes.index(where: {$0.rawValue.caseInsensitiveCompare(name) == .orderedSame})!
        return _attributes[idx]
    }

    //A name=value pair should be translated to two properties, Name=name and Value=value
    private class func createNameValuePair(pair: String) -> [String] {
        if pair.caseInsensitiveCompare(HTTPCookiePropertyKey.secure.rawValue) == .orderedSame {
            return ["Secure=TRUE"]
        }
        let name = pair.components(separatedBy: "=")[0]
        let value = pair.components(separatedBy: "\(name)=")[1]
        if !isCookieAttribute(name) {
            return ["Name=\(name)", "Value=\(value)"]
        }
        return [pair]
    }

    /// Returns a dictionary representation of the receiver.
    ///
    /// This method returns a dictionary representation of the
    /// `NSHTTPCookie` which can be saved and passed to
    /// `init(properties:)` later to reconstitute an equivalent cookie.
    ///
    /// See the `NSHTTPCookie` `init(properties:)` method for
    /// more information on the constraints imposed on the dictionary, and
    /// for descriptions of the supported keys and values.
    ///
    /// - Experiment: This is a draft API currently under consideration for official import into Foundation as a suitable alternative
    /// - Note: Since this API is under consideration it may be either removed or revised in the near future
    open var properties: [HTTPCookiePropertyKey : Any]? {
        return _properties
    }

    /// The version of the receiver.
    ///
    /// Version 0 maps to "old-style" Netscape cookies.
    /// Version 1 maps to RFC2965 cookies. There may be future versions.
    open var version: Int {
        return _version
    }

    /// The name of the receiver.
    open var name: String {
        return _name
    }

    /// The value of the receiver.
    open var value: String {
        return _value
    }

    /// Returns The expires date of the receiver.
    ///
    /// The expires date is the date when the cookie should be
    /// deleted. The result will be nil if there is no specific expires
    /// date. This will be the case only for *session-only* cookies.
    /*@NSCopying*/ open var expiresDate: Date? {
        return _expiresDate
    }

    /// Whether the receiver is session-only.
    ///
    /// `true` if this receiver should be discarded at the end of the
    /// session (regardless of expiration date), `false` if receiver need not
    /// be discarded at the end of the session.
    open var isSessionOnly: Bool {
        return _sessionOnly
    }

    /// The domain of the receiver.
    ///
    /// This value specifies URL domain to which the cookie
    /// should be sent. A domain with a leading dot means the cookie
    /// should be sent to subdomains as well, assuming certain other
    /// restrictions are valid. See RFC 2965 for more detail.
    open var domain: String {
        return _domain
    }
    
    /// The path of the receiver.
    ///
    /// This value specifies the URL path under the cookie's
    /// domain for which this cookie should be sent. The cookie will also
    /// be sent for children of that path, so `"/"` is the most general.
    open var path: String {
        return _path
    }
   
    /// Whether the receiver should be sent only over secure channels
    ///
    /// Cookies may be marked secure by a server (or by a javascript).
    /// Cookies marked as such must only be sent via an encrypted connection to
    /// trusted servers (i.e. via SSL or TLS), and should not be delievered to any
    /// javascript applications to prevent cross-site scripting vulnerabilities. 
    open var isSecure: Bool {
        return _secure
    }

    /// Whether the receiver should only be sent to HTTP servers per RFC 2965
    ///
    /// Cookies may be marked as HTTPOnly by a server (or by a javascript).
    /// Cookies marked as such must only be sent via HTTP Headers in HTTP Requests
    /// for URL's that match both the path and domain of the respective Cookies.
    /// Specifically these cookies should not be delivered to any javascript
    /// applications to prevent cross-site scripting vulnerabilities.
    open var isHTTPOnly: Bool {
        return _HTTPOnly
    }

    /// The comment of the receiver.
    ///
    /// This value specifies a string which is suitable for
    /// presentation to the user explaining the contents and purpose of this
    /// cookie. It may be nil.
    open var comment: String? {
        return _comment
    }

    /// The comment URL of the receiver.
    ///
    /// This value specifies a URL which is suitable for
    /// presentation to the user as a link for further information about
    /// this cookie. It may be nil.
    /*@NSCopying*/ open var commentURL: URL? {
        return _commentURL
    }

    /// The list ports to which the receiver should be sent.
    ///
    /// This value specifies an NSArray of NSNumbers
    /// (containing integers) which specify the only ports to which this
    /// cookie should be sent.
    ///
    /// The array may be nil, in which case this cookie can be sent to any
    /// port.
    open var portList: [NSNumber]? {
        return _portList
    }
}

//utils for cookie parsing
fileprivate extension String {
    func trim() -> String {
        return self.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)
    }

    func removeCommas() -> String {
        return self.replacingOccurrences(of: ",", with: "")
    }

    func insertComma(at index:Int) -> String {
        return  String(self.characters.prefix(index)) + ","  + String(self.characters.suffix(self.characters.count-index))
    }
}

