<commit_before>//
//  Trakt.swift
//  Arsonik
//
//  Created by <NAME> on 08/04/15.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

import Foundation
import Alamofire

/// Main Class
public class Trakt {
	internal let clientId: String
    internal let clientSecret: String
    internal let applicationId: Int
    private var token: TraktToken?
	internal var retryInterval: Double = 5
	private var attempts = NSCache()
	internal var maximumAttempt: Int = 5
    private let manager: Manager

	public typealias GeneratedCodeResponse = (deviceCode: String, userCode: String, verificationUrl: String, expiresAt: NSDate, interval: NSTimeInterval)
	public typealias JSONHash = [String: AnyObject!]

    public init(clientId: String, clientSecret: String, applicationId: Int) {
		self.clientId = clientId
		self.clientSecret = clientSecret
        self.applicationId = applicationId

        manager = Manager()

        // autoload token
        if let storedToken = TraktToken.load(clientId) {
            token = storedToken
        }
	}

	public func hasValidToken() -> Bool {
		return token != nil
	}
	
	public func clearToken() {
		token?.remove(clientId)
		token = nil
	}

	public func saveToken(token: TraktToken) {
		token.save(clientId)
		self.token = token
	}

	internal lazy var dateFormatter: NSDateFormatter = {
		let df = NSDateFormatter()
		df.locale = NSLocale(localeIdentifier: "en_US_POSIX")
		df.timeZone = NSTimeZone(forSecondsFromGMT: 0)
		df.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'.000Z'"
		return df
	}()

	internal func query(route: TraktRoute, completionHandler: Response<AnyObject, NSError> -> Void) -> Request! {
		let request = route.URLRequest
		request.setValue("2", forHTTPHeaderField: "trakt-api-version")
		request.setValue(clientId, forHTTPHeaderField: "trakt-api-key")

		if route.needAuthorization() {
			if let accessToken = token?.accessToken {
				request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
			} else {
				print("You need an access token that call that resource")
				return nil
			}
		}

		let key = "\(route.hashValue)"
		return manager.request(request).responseJSON { [weak self] response in
			if let interval = self?.retryInterval where response.response?.statusCode >= 500 && route.retryOnFailure() {
				var attempt: Int = self?.attempts.objectForKey(key) as? Int ?? 1
				self?.attempts.setObject(++attempt, forKey: key)
				if attempt < self!.maximumAttempt {
					return delay(interval) {
						self?.query(route, completionHandler: completionHandler)
					}
				} else {
					print("Maximum attempt reached for request \(route)")
				}
			}
			self?.attempts.removeObjectForKey(key)
			completionHandler(response)
		}
	}
}<commit_msg>fix conflict<commit_after>//
//  Trakt.swift
//  Arsonik
//
//  Created by <NAME> on 08/04/15.
//  Copyright (c) 2015 <NAME>. All rights reserved.
//

import Foundation
import Alamofire

/// Main Class
public class Trakt {
	internal let clientId: String
    internal let clientSecret: String
    internal let applicationId: Int
    private var token: TraktToken?
	internal var retryInterval: Double = 5
	private var attempts = NSCache()
	internal var maximumAttempt: Int = 5
    private let manager: Manager
    public let traktApiVersion = 2

	public typealias GeneratedCodeResponse = (deviceCode: String, userCode: String, verificationUrl: String, expiresAt: NSDate, interval: NSTimeInterval)
	public typealias JSONHash = [String: AnyObject!]

    public init(clientId: String, clientSecret: String, applicationId: Int) {
		self.clientId = clientId
		self.clientSecret = clientSecret
        self.applicationId = applicationId

        manager = Manager()

        // autoload token
        if let storedToken = TraktToken.load(clientId) {
            token = storedToken
        }
	}

	public func hasValidToken() -> Bool {
		return token != nil
	}
	
	public func clearToken() {
		token?.remove(clientId)
		token = nil
	}

	public func saveToken(token: TraktToken) {
		token.save(clientId)
		self.token = token
	}

	internal func query(route: TraktRoute, completionHandler: Response<AnyObject, NSError> -> Void) -> Request! {
		let request = route.URLRequest
		request.setValue("\(traktApiVersion)", forHTTPHeaderField: "trakt-api-version")
		request.setValue(clientId, forHTTPHeaderField: "trakt-api-key")

		if route.needAuthorization() {
			if let accessToken = token?.accessToken {
				request.setValue("Bearer \(accessToken)", forHTTPHeaderField: "Authorization")
			} else {
				print("You need an access token that call that resource")
				return nil
			}
		}

		let key = route.hashValue
		return manager.request(request).responseJSON { [weak self] response in
			if let interval = self?.retryInterval where response.response?.statusCode >= 500 && route.retryOnFailure() {
                var attempt: Int = self?.attempts.objectForKey(key) as? Int ?? 0
                attempt += 1
				self?.attempts.setObject(attempt, forKey: key)
				if attempt < self?.maximumAttempt {
					return delay(interval) {
						self?.query(route, completionHandler: completionHandler)
					}
				} else {
					print("Maximum attempt \(attempt)/\(self?.maximumAttempt) reached for request \(route)")
				}
			}
			self?.attempts.removeObjectForKey(key)
			completionHandler(response)
		}
	}
}
{'fraction_non_alphanumeric': 0.10845415176049708, 'fraction_numerical': 0.007343249858783657, 'mean_word_length': 3.559656652360515, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 17, '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': '3804498', 'n_tokens_mistral': 1782, 'n_tokens_neox': 1555, 'n_words': 432}