<commit_before>import Foundation

let TimberjackRequestHandledKey = "Timberjack"

public class Timberjack: NSURLProtocol {
    var connection: NSURLConnection?
    var data: NSMutableData?
    var response: NSURLResponse?
    
    //MARK: - NSURLProtocol
    
    public override class func canInitWithRequest(request: NSURLRequest) -> Bool {
        guard self.propertyForKey(TimberjackRequestHandledKey, inRequest: request) != nil else {
            return false
        }
        
        return true
    }
    
    public override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest {
        return request
    }
    
    public override class func requestIsCacheEquivalent(a: NSURLRequest, toRequest b: NSURLRequest) -> Bool {
        return super.requestIsCacheEquivalent(a, toRequest: b)
    }

    public override func startLoading() {
        guard let newRequest = request.mutableCopy() as? NSMutableURLRequest else { return }
        
        Timberjack.setProperty(true, forKey: TimberjackRequestHandledKey, inRequest: newRequest)
        connection = NSURLConnection(request: newRequest, delegate: self)
        
        print("---------------------")
        
        if let url = newRequest.URL?.absoluteString {
            print("Request: \(url)")
        }
        
        print("Method: \(newRequest.HTTPMethod)")
        
        if let headers = newRequest.allHTTPHeaderFields {
            print("Headers: [")
            for (key, value) in headers {
                print("  \(key) : \(value)")
            }
            print("]")
        }
    }
    
    public override func stopLoading() {
        connection?.cancel()
        connection = nil
    }
}<commit_msg>Added logging levels for Verbose and Light<commit_after>import Foundation

let TimberjackRequestHandledKey = "Timberjack"
let TimberjackRequestTimeKey = "TimberjackRequestTime"

public enum Style {
    case Verbose
    case Light
}

public class Timberjack: NSURLProtocol {
    var connection: NSURLConnection?
    var data: NSMutableData?
    var response: NSURLResponse?
    
    public static var logStyle: Style = .Verbose
    
    public class func register() {
        self.registerClass(self)
    }
    
    public class func unregister() {
        self.unregisterClass(self)
    }
    
    //MARK: - NSURLProtocol
    
    public override class func canInitWithRequest(request: NSURLRequest) -> Bool {
        guard self.propertyForKey(TimberjackRequestHandledKey, inRequest: request) != nil else {
            return false
        }
        
        return true
    }
    
    public override class func canonicalRequestForRequest(request: NSURLRequest) -> NSURLRequest {
        return request
    }
    
    public override class func requestIsCacheEquivalent(a: NSURLRequest, toRequest b: NSURLRequest) -> Bool {
        return super.requestIsCacheEquivalent(a, toRequest: b)
    }

    public override func startLoading() {
        guard let newRequest = request.mutableCopy() as? NSMutableURLRequest else { return }
        
        Timberjack.setProperty(true, forKey: TimberjackRequestHandledKey, inRequest: newRequest)
        Timberjack.setProperty(NSDate(), forKey: TimberjackRequestTimeKey, inRequest: newRequest)
        
        connection = NSURLConnection(request: newRequest, delegate: self)
        
        logRequest(newRequest)
    }
    
    public override func stopLoading() {
        connection?.cancel()
        connection = nil
    }
    
    // MARK: NSURLConnectionDelegate
    
    func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
        let policy = NSURLCacheStoragePolicy(rawValue: request.cachePolicy.rawValue) ?? .NotAllowed
        client?.URLProtocol(self, didReceiveResponse: response, cacheStoragePolicy: policy)
        
        self.response = response
        self.data = NSMutableData()
    }
    
    func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
        client?.URLProtocol(self, didLoadData: data)
        self.data?.appendData(data)
    }
    
    func connectionDidFinishLoading(connection: NSURLConnection!) {
        client?.URLProtocolDidFinishLoading(self)
        
        if let response = response {
            logResponse(response, data: data)
        }
    }
    
    func connection(connection: NSURLConnection!, didFailWithError error: NSError!) {
        client?.URLProtocol(self, didFailWithError: error)
        logError(error)
    }
    
    //MARK: - Logging
    
    public func logDivider() {
        print("---------------------")
    }
    
    public func logError(error: NSError) {
        logDivider()
        
        print("Error: \(error.localizedDescription)")
        
        if Timberjack.logStyle == .Verbose {
            if let reason = error.localizedFailureReason {
                print("Reason: \(reason)")
            }
            
            if let suggestion = error.localizedRecoverySuggestion {
                print("Suggestion: \(suggestion)")
            }
        }
    }
    
    public func logRequest(request: NSURLRequest) {
        logDivider()
        
        if let url = request.URL?.absoluteString {
            print("Request: \(request.HTTPMethod) \(url)")
        }
        
        if Timberjack.logStyle == .Verbose {
            if let headers = request.allHTTPHeaderFields {
                self.logHeaders(headers)
            }
        }
    }
    
    public func logResponse(response: NSURLResponse, data: NSData? = nil) {
        logDivider()
        
        if let url = response.URL?.absoluteString {
            print("Response: \(url)")
        }
        
        if let httpResponse = response as? NSHTTPURLResponse {
            let localisedStatus = NSHTTPURLResponse.localizedStringForStatusCode(httpResponse.statusCode).capitalizedString
            print("Status: \(httpResponse.statusCode) - \(localisedStatus)")
        }
        
        if Timberjack.logStyle == .Verbose {
            if let headers = (response as? NSHTTPURLResponse)?.allHeaderFields as? [String: AnyObject] {
                self.logHeaders(headers)
            }
            
            if let startDate = Timberjack.propertyForKey(TimberjackRequestTimeKey, inRequest: request) as? NSDate {
                let difference = startDate.timeIntervalSinceNow
                print("Duration: \(difference) secs")
            }
            
            guard let data = data else { return }
            
            do {
                let json = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers)
                let pretty = try NSJSONSerialization.dataWithJSONObject(json, options: .PrettyPrinted)
                
                if let string = NSString(data: pretty, encoding: NSUTF8StringEncoding) {
                    print("JSON: \(string)")
                }
            }
                
            catch {
                if let string = NSString(data: data, encoding: NSUTF8StringEncoding) {
                    print("Data: \(string)")
                }
            }
        }
    }
    
    public func logHeaders(headers: [String: AnyObject]) {
        print("Headers: [")
        for (key, value) in headers {
            print("  \(key) : \(value)")
        }
        print("]")
    }
}
{'fraction_non_alphanumeric': 0.09155313351498638, 'fraction_numerical': 0.00027247956403269756, 'mean_word_length': 2.0384933774834435, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, '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': '5412473', 'n_tokens_mistral': 1941, 'n_tokens_neox': 1903, 'n_words': 446}