<commit_before>//
//  API.swift
//  RestClient
//
//  Created by <NAME> on 10/03/16.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation
import Genome
import Alamofire
import UIKit

open class API <T where T: NodeInitializable> {
    
    open var path: URLRequest
    open var queryParams: [String: String]?
    open var bodyParams: [String: Any]?
    open var method: HTTPMethod
    open var headers: [String: String] = [:]
    open var interceptors: [Interceptor] = []
    open var logger: Logger?
    
    var curl: String?
    
    var manager : Alamofire.SessionManager
    
    
    public init(path: URL, method: HTTPMethod, queryParams: [String: String]?, bodyParams: [String: Any]?, headers: [String: String]?, interceptors: [Interceptor]?) {
        
        self.path = try! URLRequest(url: path, method: method)
        
        self.queryParams = queryParams
        self.bodyParams = bodyParams
        self.method = method
        if headers != nil {
            self.headers = headers!
        }
        
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 30
        manager = Alamofire.SessionManager(configuration: configuration)
        
        if interceptors != nil {self.interceptors.append(contentsOf: interceptors!)}
    }
    
    func beforeRequest() {
        for interceptor in interceptors {
            interceptor.requestInterceptor(self)
        }
        if queryParams != nil {
            self.path = try! URLEncoding.queryString.encode(self.path, with: queryParams)
        }
    }
    
    
    open func processJSONResponse(_ onSuccess: @escaping (_ result: Response<T>?) -> Void, onError: @escaping (RestError?) -> Void, always: @escaping () -> Void)
        -> ((_ response: DataResponse<Any>) -> Void) {
            
            return { (response: DataResponse<Any>) -> Void in
                
                for interceptor in self.interceptors {
                    interceptor.responseInterceptor(self, response: response)
                }
                
                
                switch response.result {
                case .success:
                    if Utils.isSuccessfulRequest(response: response) {
                        var instance: T? = nil // For empty results
                        if let _ = response.result.value {
                            
                            let node = try! response.data!.makeNode()
                            instance = try! T(node: node)
                        }
                        let responseBody = Response<T>(response.response?.statusCode, body: instance)
                        onSuccess(responseBody)
                    } else {
                        let error = RestError(rawValue: response.response?.statusCode ?? RestErrorType.unknow.rawValue,
                                              rawIsHttpCode: true,
                                              rawResponse: response.result.value,
                                              rawResponseData: response.data)
                        onError(error)
                    }
                case .failure(let _error):
                    
                    let errorType = response.response?.statusCode ?? RestErrorType.unknow.rawValue
                    
                    let error = RestError(rawValue: _error._code == NSURLErrorTimedOut ? RestErrorType.noNetwork.rawValue : errorType,
                                          rawIsHttpCode: true,
                                          rawResponse: response.result.value,
                                          rawResponseData: response.data)
                    onError(error)
                default:
                    let error = RestError(rawValue: response.response?.statusCode ?? RestErrorType.unknow.rawValue,
                                          rawIsHttpCode: true,
                                          rawResponse: response.result.value,
                                          rawResponseData: response.data)
                    onError(error)
                }
                
                always()
            }
    }
    
    open func upload(_ onProgress: @escaping (_ progress: Float) -> Void, onSuccess: @escaping (_ result: Response<T>?) -> Void,
                     onError: @escaping (RestError?) -> Void,
                     always: @escaping () -> Void) {
        
        assert(self.method == .post)
        assert((self.bodyParams?.count ?? 0) == 1)
        
        self.beforeRequest()<commit_msg>fix empty body response error<commit_after>//
//  API.swift
//  RestClient
//
//  Created by Guizion Labs on 10/03/16.
//  Copyright © 2016 Guizion Labs. All rights reserved.
//

import Foundation
import Genome
import Alamofire
import UIKit

open class API <T where T: NodeInitializable> {
    
    open var path: URLRequest
    open var queryParams: [String: String]?
    open var bodyParams: [String: Any]?
    open var method: HTTPMethod
    open var headers: [String: String] = [:]
    open var interceptors: [Interceptor] = []
    open var logger: Logger?
    
    var curl: String?
    
    var manager : Alamofire.SessionManager
    
    let noNetWorkCodes = Set([
        NSURLErrorCannotFindHost,
        NSURLErrorCannotConnectToHost,
        NSURLErrorNetworkConnectionLost,
        NSURLErrorDNSLookupFailed,
        NSURLErrorHTTPTooManyRedirects,
        NSURLErrorNotConnectedToInternet
        ])
    
    public init(path: URL, method: HTTPMethod, queryParams: [String: String]?, bodyParams: [String: Any]?, headers: [String: String]?, interceptors: [Interceptor]?) {
        
        self.path = try! URLRequest(url: path, method: method)
        
        self.queryParams = queryParams
        self.bodyParams = bodyParams
        self.method = method
        if headers != nil {
            self.headers = headers!
        }
        
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForRequest = 30
        manager = Alamofire.SessionManager(configuration: configuration)
        
        if interceptors != nil {self.interceptors.append(contentsOf: interceptors!)}
    }
    
    func beforeRequest() {
        for interceptor in interceptors {
            interceptor.requestInterceptor(self)
        }
        if queryParams != nil {
            self.path = try! URLEncoding.queryString.encode(self.path, with: queryParams)
        }
    }
    
    
    open func processJSONResponse(_ onSuccess: @escaping (_ result: Response<T>?) -> Void, onError: @escaping (RestError?) -> Void, always: @escaping () -> Void)
        -> ((_ response: DataResponse<Any>) -> Void) {
            
            return { (response: DataResponse<Any>) -> Void in
                
                for interceptor in self.interceptors {
                    interceptor.responseInterceptor(self, response: response)
                }
                
                
                switch response.result {
                case .success:
                    if Utils.isSuccessfulRequest(response: response) {
                        var instance: T? = nil // For empty results
                        if let _ = response.result.value {
                            if let node = try? response.data!.makeNode() {
                                instance = try! T(node: node)
                            }
                        }
                        let responseBody = Response<T>(response.response?.statusCode, body: instance)
                        onSuccess(responseBody)
                    } else {
                        let error = RestError(rawValue: response.response?.statusCode ?? RestErrorType.unknow.rawValue,
                                              rawIsHttpCode: true,
                                              rawResponse: response.result.value,
                                              rawResponseData: response.data)
                        onError(error)
                    }
                case .failure(let _error):
                    
                    let errorType = response.response?.statusCode ?? (self.noNetWorkCodes.contains(_error._code) ? RestErrorType.noNetwork.rawValue :RestErrorType.unknow.rawValue)
                    
                    let error = RestError(rawValue: _error._code == NSURLErrorTimedOut ? RestErrorType.noNetwork.rawValue : errorType,
                                          rawIsHttpCode: true,
                                          rawResponse: response.result.value,
                                          rawResponseData: response.data)
                    onError(error)
                default:
                    let error = RestError(rawValue: response.response?.statusCode ?? RestErrorType.unknow.rawValue,
                                          rawIsHttpCode: true,
                                          rawResponse: response.result.value,
                                          rawResponseData: response.data)
                    onError(error)
                }
                
                always()
            }
    }
    
    open func upload(_ onProgress: @escaping (_ progress: Float) -> Void, onSuccess: @escaping (_ result: Response<T>?) -> Void,
                     onError: @escaping (RestError?) -> Void,
                     always: @escaping () -> Void) {
        
        assert(self.method == .post)
        assert((self.bodyParams?.count ?? 0) == 1)
        
        self.beforeRequest()
{'fraction_non_alphanumeric': 0.08536713103592751, 'fraction_numerical': 0.002932858489577878, 'mean_word_length': 1.4221207508878742, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 39, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4118098', 'n_tokens_mistral': 2347, 'n_tokens_neox': 2198, 'n_words': 543}