// Foundation/NSURLSession/HTTPMessage.swift - HTTP Message parsing
//
// 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
//
// -----------------------------------------------------------------------------
///
/// Helpers for parsing HTTP responses.
/// These are libcurl helpers for the URLSession API code.
/// - SeeAlso: https://curl.haxx.se/libcurl/c/
/// - SeeAlso: NSURLSession.swift
///
// -----------------------------------------------------------------------------

import CoreFoundation


extension URLSessionTask {
    /// An HTTP header being parsed.
    ///
    /// It can either be complete (i.e. the final CR LF CR LF has been
    /// received), or partial.
    internal enum _ParsedResponseHeader {
        case partial(_ResponseHeaderLines)
        case complete(_ResponseHeaderLines)
        init() {
            self = .partial(_ResponseHeaderLines())
        }
    }
    /// A type safe wrapper around multiple lines of headers.
    ///
    /// This can be converted into an `NSHTTPURLResponse`.
    internal struct _ResponseHeaderLines {
        let lines: [String]
        init() {
            self.lines = []
        }
        init(headerLines: [String]) {
            self.lines = headerLines
        }
    }
}

extension URLSessionTask._ParsedResponseHeader {
    /// Parse a header line passed by libcurl.
    ///
    /// These contain the <CRLF> ending and the final line contains nothing but
    /// that ending.
    /// - Returns: Returning nil indicates failure. Otherwise returns a new
    ///     `ParsedResponseHeader` with the given line added.
    func byAppending(headerLine data: Data) -> URLSessionTask._ParsedResponseHeader? {
        // The buffer must end in CRLF
        guard
            2 <= data.count &&
                data[data.endIndex - 2] == _HTTPCharacters.CR &&
                data[data.endIndex - 1] == _HTTPCharacters.LF
            else { return nil }
        let lineBuffer = data.subdata(in: Range(data.startIndex..<data.endIndex-2))
        guard let line = String(data: lineBuffer, encoding: String.Encoding.utf8) else { return nil}
        return byAppending(headerLine: line)
    }
    /// Append a status line.
    ///
    /// If the line is empty, it marks the end of the header, and the result
    /// is a complete header. Otherwise it's a partial header.
    /// - Note: Appending a line to a complete header results in a partial
    ///     header with just that line.
    private func byAppending(headerLine line: String) -> URLSessionTask._ParsedResponseHeader {
        if line.isEmpty {
            switch self {
            case .partial(let header): return .complete(header)
            case .complete: return .partial(URLSessionTask._ResponseHeaderLines())
            }
        } else {
            let header = partialResponseHeader
            return .partial(header.byAppending(headerLine: line))
        }
    }
    private var partialResponseHeader: URLSessionTask._ResponseHeaderLines {
        switch self {
        case .partial(let header): return header
        case .complete: return URLSessionTask._ResponseHeaderLines()
        }
    }
}
private extension URLSessionTask._ResponseHeaderLines {
    /// Returns a copy of the lines with the new line appended to it.
    func byAppending(headerLine line: String) -> URLSessionTask._ResponseHeaderLines {
        var l = self.lines
        l.append(line)
        return URLSessionTask._ResponseHeaderLines(headerLines: l)
    }
}
internal extension URLSessionTask._ResponseHeaderLines {
    /// Create an `NSHTTPRULResponse` from the lines.
    ///
    /// This will parse the header lines.
    /// - Returns: `nil` if an error occured while parsing the header lines.
    func createHTTPURLResponse(for URL: URL) -> HTTPURLResponse? {
        guard let message = createHTTPMessage() else { return nil }
        return HTTPURLResponse(message: message, URL: URL)
    }
    /// Parse the lines into a `URLSessionTask.HTTPMessage`.
    func createHTTPMessage() -> URLSessionTask._HTTPMessage? {
        guard let (head, tail) = lines.decompose else { return nil }
        guard let startline = URLSessionTask._HTTPMessage._StartLine(line: head) else { return nil }
        guard let headers = createHeaders(from: tail) else { return nil }
        return URLSessionTask._HTTPMessage(startLine: startline, headers: headers)
    }
}

extension HTTPURLResponse {
    fileprivate convenience init?(message: URLSessionTask._HTTPMessage, URL: URL) {
        /// This needs to be a request, i.e. it needs to have a status line.
        guard case .statusLine(let statusLine) = message.startLine else { return nil }
        let fields = message.headersAsDictionary
        self.init(url: URL, statusCode: statusLine.status, httpVersion: statusLine.version.rawValue, headerFields: fields)
    }
}


extension URLSessionTask {
    /// HTTP Message
    ///
    /// A message consist of a *start-line* optionally followed by one or multiple
    /// message-header lines, and optionally a message body.
    ///
    /// This represents everything except for the message body.
    ///
    /// - SeeAlso: https://tools.ietf.org/html/rfc2616#section-4
    struct _HTTPMessage {
        let startLine: URLSessionTask._HTTPMessage._StartLine
        let headers: [URLSessionTask._HTTPMessage._Header]
    }
}

extension URLSessionTask._HTTPMessage {
    var headersAsDictionary: [String: String] {
        var result: [String: String] = [:]
        headers.forEach {
            result[$0.name] = $0.value
        }
        return result
    }
}
extension URLSessionTask._HTTPMessage {
    /// A single HTTP message header field
    ///
    /// Most HTTP messages have multiple header fields.
    struct _Header {
        let name: String
        let value: String
    }
    /// The first line of a HTTP message
    ///
    /// This can either be the *request line* (RFC 2616 Section 5.1) or the
    /// *status line* (RFC 2616 Section 6.1)
    enum _StartLine {
        /// RFC 2616 Section 5.1 *Request Line*
        /// - SeeAlso: https://tools.ietf.org/html/rfc2616#section-5.1
        case requestLine(method: String, uri: URL, version: URLSessionTask._HTTPMessage._Version)
        /// RFC 2616 Section 6.1 *Status Line*
        /// - SeeAlso: https://tools.ietf.org/html/rfc2616#section-6.1
        case statusLine(version: URLSessionTask._HTTPMessage._Version, status: Int, reason: String)
    }
    /// A HTTP version, e.g. "HTTP/1.1"
    struct _Version: RawRepresentable {
        let rawValue: String
    }
}
extension URLSessionTask._HTTPMessage._Version {
    init?(versionString: String) {
        rawValue = versionString
    }
}


// Characters that we need for HTTP parsing:

struct _HTTPCharacters {
    /// *Carriage Return* symbol
    static let CR: UInt8 = 0x0d
    /// *Line Feed* symbol
    static let LF: UInt8 = 0x0a
    /// *Space* symbol
    static let Space = UnicodeScalar(0x20)
    static let HorizontalTab = UnicodeScalar(0x09)
    static let Colon = UnicodeScalar(0x3a)
    /// *Separators* according to RFC 2616
    static let Separators = NSCharacterSet(charactersIn: "()<>@,;:\\\"/[]?={} \t")
}

private extension URLSessionTask._HTTPMessage._StartLine {
    init?(line: String) {
        guard let r = line.splitRequestLine() else { return nil }
        if let version = URLSessionTask._HTTPMessage._Version(versionString: r.0) {
            // Status line:
            guard let status = Int(r.1), 100 <= status && status <= 999 else { return nil }
            self = .statusLine(version: version, status: status, reason: r.2)
        } else if let version = URLSessionTask._HTTPMessage._Version(versionString: r.2),
            let URI = URL(string: r.1) {
            // The request method must be a token (i.e. without seperators):
            let seperatorIdx = r.0.unicodeScalars.index(where: { !$0.isValidMessageToken } )
            guard seperatorIdx == nil else { return nil }
            self = .requestLine(method: r.0, uri: URI, version: version)
        } else {
            return nil
        }
    }
}
private extension String {
    /// Split a request line into its 3 parts: *Method*, *Request-URI*, and *HTTP-Version*.
    /// - SeeAlso: https://tools.ietf.org/html/rfc2616#section-5.1
    func splitRequestLine() -> (String, String, String)? {
        let scalars = self.unicodeScalars
        guard let firstSpace = scalars.rangeOfSpace else { return nil }
        let remainingRange = firstSpace.upperBound..<scalars.endIndex
        let remainder = scalars[remainingRange]
        guard let secondSpace = remainder.rangeOfSpace else { return nil }
        let methodRange = scalars.startIndex..<firstSpace.lowerBound
        let uriRange = remainder.startIndex..<secondSpace.lowerBound
        let versionRange = secondSpace.upperBound..<remainder.endIndex
      
        //TODO: is this necessary? If yes, this guard needs an alternate implementation 
        //guard 0 < methodRange.count && 0 < uriRange.count && 0 < versionRange.count else { return nil } 

        let m = String(scalars[methodRange])
        let u = String(remainder[uriRange])
        let v = String(remainder[versionRange])
        return (m, u, v)
    }
}

/// Parses an array of lines into an array of
/// `URLSessionTask.HTTPMessage.Header`.
///
/// This respects the header folding as described by
/// https://tools.ietf.org/html/rfc2616#section-2.2 :
///
/// - SeeAlso: `URLSessionTask.HTTPMessage.Header.createOne(from:)`
private func createHeaders(from lines: ArraySlice<String>) -> [URLSessionTask._HTTPMessage._Header]? {

    var headerLines = Array(lines)
    var headers: [URLSessionTask._HTTPMessage._Header] = []
    while !headerLines.isEmpty {
        guard let (header, remaining) = URLSessionTask._HTTPMessage._Header.createOne(from: headerLines) else { return nil }
        headers.append(header)
        headerLines = remaining
    }
    return headers
}
private extension URLSessionTask._HTTPMessage._Header {
    /// Parse a single HTTP message header field
    ///
    /// Each header field consists
    /// of a name followed by a colon (":") and the field value. Field names
    /// are case-insensitive. The field value MAY be preceded by any amount
    /// of LWS, though a single SP is preferred. Header fields can be
    /// extended over multiple lines by preceding each extra line with at
    /// least one SP or HT. Applications ought to follow "common form", where
    /// one is known or indicated, when generating HTTP constructs, since
    /// there might exist some implementations that fail to accept anything
    /// beyond the common forms.
    ///
    /// Consumes lines from the given array of lines to produce a single HTTP
    /// message header and returns the resulting header plus the remainder.
    ///
    /// If an error occurs, it returns `nil`.
    ///
    /// - SeeAlso: https://tools.ietf.org/html/rfc2616#section-4.2
    static func createOne(from lines: [String]) -> (URLSessionTask._HTTPMessage._Header, [String])? {
        // HTTP/1.1 header field values can be folded onto multiple lines if the
        // continuation line begins with a space or horizontal tab. All linear
        // white space, including folding, has the same semantics as SP. A
        // recipient MAY replace any linear white space with a single SP before
        // interpreting the field value or forwarding the message downstream.
        guard let (head, tail) = lines.decompose else { return nil }
        let headView = head.unicodeScalars
        guard let nameRange = headView.rangeOfTokenPrefix else { return nil }
        guard headView.index(after: nameRange.upperBound) <= headView.endIndex && headView[nameRange.upperBound] == _HTTPCharacters.Colon else { return nil }
        let name = String(headView[nameRange])
        var value: String?
        let line = headView[headView.index(after: nameRange.upperBound)..<headView.endIndex]
        if !line.isEmpty {
            guard let v = line.trimSPHTPrefix else { return nil }
            value = String(v)
        }
        do {
            var t = tail
            while t.first?.unicodeScalars.hasSPHTPrefix ?? false {
                guard let (h2, t2) = t.decompose else { return nil }
                t = t2
                guard let v = h2.unicodeScalars.trimSPHTPrefix else { return nil }
                let valuePart = String(v)
                value = value.map { $0 + " " + valuePart } ?? valuePart
            }
            return (URLSessionTask._HTTPMessage._Header(name: name, value: value ?? ""), Array(t))
        }
    }
}
private extension Collection {
    /// Splits the collection into its first element and the remainder.
    var decompose: (Iterator.Element, Self.SubSequence)? {
        guard let head = self.first else { return nil }
        let tail = self[self.index(after: startIndex)..<endIndex]
        return (head, tail)
    }
}
private extension String.UnicodeScalarView {
    /// The range of *Token* characters as specified by RFC 2616.
    var rangeOfTokenPrefix: Range<Index>? {
        var end = startIndex
        while self[end].isValidMessageToken {
            end = self.index(after: end)
        }
        guard end != startIndex else { return nil }
        return startIndex..<end
    }
    /// The range of space (U+0020) characters.
    var rangeOfSpace: Range<Index>? {
        guard !isEmpty else { return startIndex..<startIndex }
        guard let idx = index(of: _HTTPCharacters.Space!) else { return nil }
        return idx..<self.index(after: idx)
    }
    // Has a space (SP) or horizontal tab (HT) prefix
    var hasSPHTPrefix: Bool {
        guard !isEmpty else { return false }
        return self[startIndex] == _HTTPCharacters.Space || self[startIndex] == _HTTPCharacters.HorizontalTab
    }
    /// Unicode scalars after removing the leading spaces (SP) and horizontal tabs (HT).
    /// Returns `nil` if the unicode scalars do not start with a SP or HT.
    var trimSPHTPrefix: String.UnicodeScalarView? {
        guard !isEmpty else { return nil }
        var idx = startIndex
        while idx < endIndex {
            if self[idx] == _HTTPCharacters.Space || self[idx] == _HTTPCharacters.HorizontalTab {
                idx = self.index(after: idx)
            } else {
                guard startIndex < idx else { return nil }
                return self[idx..<endIndex]
            }
        }
        return nil
    }
}
private extension UnicodeScalar {
    /// Is this a valid **token** as defined by RFC 2616 ?
    ///
    /// - SeeAlso: https://tools.ietf.org/html/rfc2616#section-2
    var isValidMessageToken: Bool {
        guard UnicodeScalar(32) <= self && self <= UnicodeScalar(126) else { return false }
        return !_HTTPCharacters.Separators.characterIsMember(UInt16(self.value))
    }
}
