<commit_before>//
//  NSClient.swift
//  Pods
//
//  Created by <NAME> on 2017/1/29.
//
//

import Foundation

public enum NSClientError: HIError {
    case missingResponse(request: HTTPRequest)
    case adaptURLRequestFailed(rawError: Error)
    case adaptURLResponseFailed(rawError: Error)
    
    public var errorDescription: String? {
        get {
            switch self {
            case .missingResponse(let request):
                return "HTTPURLResponse为空, request: \(request)"
            case .adaptURLRequestFailed(let error):
                return "生成URLRequest出错, 原始错误: \(error)"
            case .adaptURLResponseFailed(let error):
                return "请求出错, 原始错误: \(error)"
            }
        }
    }
}

class NSRequestFuture: NSObject, HTTPRequestFuture {
    let request: HTTPRequest
    let queue: DispatchQueue
    var task: URLSessionDataTask? {
        set {
            _task = newValue
        }
        get { return _task }
    }
    var progressHandler: ((Progress) -> Void)?
    var responseHandler: ((HTTPResponse) -> Void)?
    var errorHandler: ((HIError) -> Void)?
    let overallProgress: Progress
    let sendProgress: Progress
    let receiveProgress: Progress
    
    
    private var _task: URLSessionDataTask? {
        willSet {
            _task?.removeObserver(self, forKeyPath: "countOfBytesReceived")
            _task?.removeObserver(self, forKeyPath: "countOfBytesSent")
            _task?.removeObserver(self, forKeyPath: "countOfBytesExpectedToReceive")
            _task?.removeObserver(self, forKeyPath: "countOfBytesExpectedToSend")
        }
        didSet {
            guard let t = _task else {
                return
            }
            t.addObserver(self, forKeyPath: "countOfBytesReceived", options: .new, context: nil)
            t.addObserver(self, forKeyPath: "countOfBytesSent", options: .new, context: nil)
            t.addObserver(self, forKeyPath: "countOfBytesExpectedToReceive", options: .new, context: nil)
            t.addObserver(self, forKeyPath: "countOfBytesExpectedToSend", options: .new, context: nil)
        }
    }
    
    deinit {
        _task?.removeObserver(self, forKeyPath: "countOfBytesReceived")
        _task?.removeObserver(self, forKeyPath: "countOfBytesSent")
        _task?.removeObserver(self, forKeyPath: "countOfBytesExpectedToReceive")
        _task?.removeObserver(self, forKeyPath: "countOfBytesExpectedToSend")
    }
    
    init(request: HTTPRequest, queue: DispatchQueue) {
        self.request = request
        self.queue = queue
        overallProgress = Progress(totalUnitCount: 2)
        overallProgress.becomeCurrent(withPendingUnitCount: overallProgress.totalUnitCount / 2)
        sendProgress = Progress(totalUnitCount: Int64.max)
        overallProgress.resignCurrent()
        overallProgress.becomeCurrent(withPendingUnitCount: overallProgress.totalUnitCount / 2)
        receiveProgress = Progress(totalUnitCount: Int64.max)
        overallProgress.resignCurrent()
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        guard let task = self.task, let keyPath = keyPath else {
            return
        }
        
        if keyPath == "countOfBytesExpectedToReceive" {
            receiveProgress.totalUnitCount = task.countOfBytesExpectedToReceive
        }
        if keyPath == "countOfBytesReceived" {
            receiveProgress.completedUnitCount = task.countOfBytesReceived
        }
        if keyPath == "countOfBytesExpectedToSend" {
            sendProgress.totalUnitCount = task.countOfBytesExpectedToSend
        }
        if keyPath == "countOfBytesSent" {
            sendProgress.completedUnitCount = task.countOfBytesSent
        }
        
        notify(progress: overallProgress)
    }
    
    private func resetProgress() {
        self.overallProgress.completedUnitCount = 0
        self.sendProgress.completedUnitCount = 0
        self.receiveProgress.completedUnitCount = 0
    }
    
    func notify(progress: Progress) {
        queue.async {
            self.progressHandler?(progress)
        }
    }
    
    func notify(response: HTTPResponse) {
        queue.async {
            self.responseHandler?(response)
        }<commit_msg>[OPT] keypath switch<commit_after>//
//  NSClient.swift
//  Pods
//
//  Created by <NAME> on 2017/1/29.
//
//

import Foundation

public enum NSClientError: HIError {
    case missingResponse(request: HTTPRequest)
    case adaptURLRequestFailed(rawError: Error)
    case adaptURLResponseFailed(rawError: Error)
    
    public var errorDescription: String? {
        get {
            switch self {
            case .missingResponse(let request):
                return "HTTPURLResponse为空, request: \(request)"
            case .adaptURLRequestFailed(let error):
                return "生成URLRequest出错, 原始错误: \(error)"
            case .adaptURLResponseFailed(let error):
                return "请求出错, 原始错误: \(error)"
            }
        }
    }
}

class NSRequestFuture: NSObject, HTTPRequestFuture {
    let request: HTTPRequest
    let queue: DispatchQueue
    var task: URLSessionDataTask? {
        set {
            _task = newValue
        }
        get { return _task }
    }
    var progressHandler: ((Progress) -> Void)?
    var responseHandler: ((HTTPResponse) -> Void)?
    var errorHandler: ((HIError) -> Void)?
    let overallProgress: Progress
    let sendProgress: Progress
    let receiveProgress: Progress
    
    
    private var _task: URLSessionDataTask? {
        willSet {
            _task?.removeObserver(self, forKeyPath: "countOfBytesReceived")
            _task?.removeObserver(self, forKeyPath: "countOfBytesSent")
            _task?.removeObserver(self, forKeyPath: "countOfBytesExpectedToReceive")
            _task?.removeObserver(self, forKeyPath: "countOfBytesExpectedToSend")
        }
        didSet {
            guard let t = _task else {
                return
            }
            t.addObserver(self, forKeyPath: "countOfBytesReceived", options: .new, context: nil)
            t.addObserver(self, forKeyPath: "countOfBytesSent", options: .new, context: nil)
            t.addObserver(self, forKeyPath: "countOfBytesExpectedToReceive", options: .new, context: nil)
            t.addObserver(self, forKeyPath: "countOfBytesExpectedToSend", options: .new, context: nil)
        }
    }
    
    deinit {
        _task?.removeObserver(self, forKeyPath: "countOfBytesReceived")
        _task?.removeObserver(self, forKeyPath: "countOfBytesSent")
        _task?.removeObserver(self, forKeyPath: "countOfBytesExpectedToReceive")
        _task?.removeObserver(self, forKeyPath: "countOfBytesExpectedToSend")
    }
    
    init(request: HTTPRequest, queue: DispatchQueue) {
        self.request = request
        self.queue = queue
        overallProgress = Progress(totalUnitCount: 2)
        overallProgress.becomeCurrent(withPendingUnitCount: overallProgress.totalUnitCount / 2)
        sendProgress = Progress(totalUnitCount: Int64.max)
        overallProgress.resignCurrent()
        overallProgress.becomeCurrent(withPendingUnitCount: overallProgress.totalUnitCount / 2)
        receiveProgress = Progress(totalUnitCount: Int64.max)
        overallProgress.resignCurrent()
    }
    
    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
        guard let task = self.task, let keyPath = keyPath else {
            return
        }
        
        switch keyPath {
        case "countOfBytesExpectedToReceive" :
            receiveProgress.totalUnitCount = task.countOfBytesExpectedToReceive
        case "countOfBytesReceived" :
            receiveProgress.completedUnitCount = task.countOfBytesReceived
        case "countOfBytesExpectedToSend" :
            sendProgress.totalUnitCount = task.countOfBytesExpectedToSend
        case "countOfBytesSent" :
            sendProgress.completedUnitCount = task.countOfBytesSent
        default: break
        }
        
        notify(progress: overallProgress)
    }
    
    private func resetProgress() {
        self.overallProgress.completedUnitCount = 0
        self.sendProgress.completedUnitCount = 0
        self.receiveProgress.completedUnitCount = 0
    }
    
    func notify(progress: Progress) {
        queue.async {
            self.progressHandler?(progress)
        }
    }
    
    func notify(response: HTTPResponse) {
        queue.async {
            self.responseHandler?(response)
        }
{'fraction_non_alphanumeric': 0.08823188405797101, 'fraction_numerical': 0.003942028985507246, 'mean_word_length': 2.4993914807302233, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4873284', 'n_tokens_mistral': 2381, 'n_tokens_neox': 2335, 'n_words': 490}