<commit_before>import Foundation

#if APIKIT_DYNAMIC_FRAMEWORK
import LlamaKit
#endif

public let APIKitErrorDomain = "APIKitErrorDomain"

public protocol Request {
    typealias Response: Any
    
    var URLRequest: NSURLRequest? { get }
    
    func responseFromObject(object: AnyObject) -> Response?
}

public enum Method: String {
    case GET = "GET"
    case POST = "POST"
    case PUT = "PUT"
    case HEAD = "HEAD"
    case DELETE = "DELETE"
    case PATCH = "PATCH"
    case TRACE = "TRACE"
    case OPTIONS = "OPTIONS"
    case CONNECT = "CONNECT"
}

// use private, global scope variable until we can use stored class var in Swift 1.2
private var instancePairDictionary = [String: (API, NSURLSession)]()

public class API: NSObject, NSURLSessionDelegate {
    // configurations
    public class func baseURL() -> NSURL {
        fatalError("API.baseURL() must be overrided in subclasses.")
    }
    
    public class func requestBodyBuilder() -> RequestBodyBuilder {
        return .JSON(writingOptions: nil)
    }

    public class func responseBodyParser() -> ResponseBodyParser {
        return .JSON(readingOptions: nil)
    }
    
    public class func URLSessionConfiguration() -> NSURLSessionConfiguration {
        return NSURLSessionConfiguration.defaultSessionConfiguration()
    }
    
    // prevent instantiation
    override private init() {
        super.init()
    }
    
    // create session and instance of API for each subclasses
    private final class var instancePair: (API, NSURLSession) {
        let className = NSStringFromClass(self)
        let pair: (API, NSURLSession) = instancePairDictionary[className] ?? {
            let instance = self.init()
            let configuration = self.URLSessionConfiguration()
            let session = NSURLSession(configuration: configuration, delegate: instance, delegateQueue: nil)
            let pair = (instance, session)
            instancePairDictionary[className] = pair
            return pair
        }()
        
        return pair
    }
    
    public final class var instance: API {
        return instancePair.0
    }
    
    public final class var URLSession: NSURLSession {
        return instancePair.1
    }

    // build NSURLRequest
    public class func URLRequest(method: Method, _ path: String, _ parameters: [String: AnyObject] = [:]) -> NSURLRequest? {
        if let components = NSURLComponents(URL: baseURL(), resolvingAgainstBaseURL: true) {
            let request = NSMutableURLRequest()<commit_msg>lock using semaphore while accessing instancePairDictionary<commit_after>import Foundation

#if APIKIT_DYNAMIC_FRAMEWORK
import LlamaKit
#endif

public let APIKitErrorDomain = "APIKitErrorDomain"

public protocol Request {
    typealias Response: Any
    
    var URLRequest: NSURLRequest? { get }
    
    func responseFromObject(object: AnyObject) -> Response?
}

public enum Method: String {
    case GET = "GET"
    case POST = "POST"
    case PUT = "PUT"
    case HEAD = "HEAD"
    case DELETE = "DELETE"
    case PATCH = "PATCH"
    case TRACE = "TRACE"
    case OPTIONS = "OPTIONS"
    case CONNECT = "CONNECT"
}

// use private, global scope variable until we can use stored class var in Swift 1.2
private var instancePairDictionary = [String: (API, NSURLSession)]()
private let instancePairSemaphore = dispatch_semaphore_create(1)

public class API: NSObject, NSURLSessionDelegate {
    // configurations
    public class func baseURL() -> NSURL {
        fatalError("API.baseURL() must be overrided in subclasses.")
    }
    
    public class func requestBodyBuilder() -> RequestBodyBuilder {
        return .JSON(writingOptions: nil)
    }

    public class func responseBodyParser() -> ResponseBodyParser {
        return .JSON(readingOptions: nil)
    }
    
    public class func URLSessionConfiguration() -> NSURLSessionConfiguration {
        return NSURLSessionConfiguration.defaultSessionConfiguration()
    }
    
    // prevent instantiation
    override private init() {
        super.init()
    }
    
    // create session and instance of API for each subclasses
    private final class var instancePair: (API, NSURLSession) {
        let className = NSStringFromClass(self)
        
        dispatch_semaphore_wait(instancePairSemaphore, DISPATCH_TIME_FOREVER)
        let pair: (API, NSURLSession) = instancePairDictionary[className] ?? {
            let instance = self.init()
            let configuration = self.URLSessionConfiguration()
            let session = NSURLSession(configuration: configuration, delegate: instance, delegateQueue: nil)
            let pair = (instance, session)
            instancePairDictionary[className] = pair
            return pair
        }()
        dispatch_semaphore_signal(instancePairSemaphore)
        
        return pair
    }
    
    public final class var instance: API {
        return instancePair.0
    }
    
    public final class var URLSession: NSURLSession {
        return instancePair.1
    }

    // build NSURLRequest
    public class func URLRequest(method: Method, _ path: String, _ parameters: [String: AnyObject] = [:]) -> NSURLRequest? {
        if let components = NSURLComponents(URL: baseURL(), resolvingAgainstBaseURL: true) {
            let request = NSMutableURLRequest()
{'fraction_non_alphanumeric': 0.08019670890864385, 'fraction_numerical': 0.0017022886324947987, 'mean_word_length': 2.845818181818182, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 15, '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': '1312207', 'n_tokens_mistral': 1420, 'n_tokens_neox': 1404, 'n_words': 431}