<commit_before>/*
Copyright (C) 2015 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information

Abstract:
This file shows an example of implementing the OperationCondition protocol.
*/

#if os(iOS)

import UIKit

public enum UserNotificationConditionError: ErrorType {
    case SettingsMismatch(currentSettings: UIUserNotificationSettings?, desiredSettings: UIUserNotificationSettings)
}

/**
    A condition for verifying that we can present alerts to the user via 
    `UILocalNotification` and/or remote notifications.
*/
public struct UserNotificationCondition: OperationCondition {
    
    public enum Behavior {
        /// Merge the new `UIUserNotificationSettings` with the `currentUserNotificationSettings`.
        case Merge

        /// Replace the `currentUserNotificationSettings` with the new `UIUserNotificationSettings`.
        case Replace
    }
    
    public static let isMutuallyExclusive = false
    
    public let settings: UIUserNotificationSettings
    public let application: UIApplication
    public let behavior: Behavior
    
    /** 
        The designated initializer.
        
        - parameter settings: The `UIUserNotificationSettings` you wish to be 
            registered.

        - parameter application: The `UIApplication` on which the `settings` should 
            be registered.

        - parameter behavior: The way in which the `settings` should be applied 
            to the `application`. By default, this value is `.Merge`, which means
            that the `settings` will be combined with the existing settings on the
            `application`. You may also specify `.Replace`, which means the `settings` 
            will overwrite the existing settings.
    */
    public init(settings: UIUserNotificationSettings, application: UIApplication, behavior: Behavior = .Merge) {
        self.settings = settings
        self.application = application
        self.behavior = behavior
    }
    
    public func dependencyForOperation(operation: Operation) -> NSOperation? {
        return UserNotificationPermissionOperation(settings: settings, application: application, behavior: behavior)
    }
    
    public func evaluateForOperation(operation: Operation, completion: OperationConditionResult -> Void) {
        let result: OperationConditionResult
        
        let current = application.currentUserNotificationSettings()

        switch (current, settings)  {
            case (let current?, let settings) where current.contains(settings):
                result = .Satisfied

            default:
                let error = UserNotificationConditionError.SettingsMismatch(currentSettings: current, desiredSettings: settings)
                
                result = .Failed(error)
        }
        
        completion(result)
    }
}

/**
    A private `Operation` subclass to register a `UIUserNotificationSettings`
    object with a `UIApplication`, prompting the user for permission if necessary.
*/
private class UserNotificationPermissionOperation: Operation {
    let settings: UIUserNotificationSettings<commit_msg>Only register notification settings if they aren't already granted<commit_after>/*
Copyright (C) 2015 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information

Abstract:
This file shows an example of implementing the OperationCondition protocol.
*/

#if os(iOS)

import UIKit

public enum UserNotificationConditionError: ErrorType {
    case SettingsMismatch(currentSettings: UIUserNotificationSettings?, desiredSettings: UIUserNotificationSettings)
}

/**
    A condition for verifying that we can present alerts to the user via 
    `UILocalNotification` and/or remote notifications.
*/
public struct UserNotificationCondition: OperationCondition {
    
    public enum Behavior {
        /// Merge the new `UIUserNotificationSettings` with the `currentUserNotificationSettings`.
        case Merge

        /// Replace the `currentUserNotificationSettings` with the new `UIUserNotificationSettings`.
        case Replace
    }
    
    public static let isMutuallyExclusive = false
    
    public let settings: UIUserNotificationSettings
    public let application: UIApplication
    public let behavior: Behavior
    
    /** 
        The designated initializer.
        
        - parameter settings: The `UIUserNotificationSettings` you wish to be 
            registered.

        - parameter application: The `UIApplication` on which the `settings` should 
            be registered.

        - parameter behavior: The way in which the `settings` should be applied 
            to the `application`. By default, this value is `.Merge`, which means
            that the `settings` will be combined with the existing settings on the
            `application`. You may also specify `.Replace`, which means the `settings` 
            will overwrite the existing settings.
    */
    public init(settings: UIUserNotificationSettings, application: UIApplication, behavior: Behavior = .Merge) {
        self.settings = settings
        self.application = application
        self.behavior = behavior
    }
    
    public func dependencyForOperation(operation: Operation) -> NSOperation? {
        if settingsMatch() {
            return nil
        } else {
            return UserNotificationPermissionOperation(settings: settings, application: application, behavior: behavior)
        }
    }
    
    public func evaluateForOperation(operation: Operation, completion: OperationConditionResult -> Void) {
        if settingsMatch() {
            completion(.Satisfied)
        } else {
            let error = UserNotificationConditionError.SettingsMismatch(currentSettings: application.currentUserNotificationSettings(), desiredSettings: settings)
            
            completion(.Failed(error))
        }
    }
    
    private func settingsMatch() -> Bool {
        guard let current = application.currentUserNotificationSettings() else { return false }
        return current.contains(settings)
    }
}

/**
    A private `Operation` subclass to register a `UIUserNotificationSettings`
    object with a `UIApplication`, prompting the user for permission if necessary.
*/
private class UserNotificationPermissionOperation: Operation {
    let settings: UIUserNotificationSettings
{'fraction_non_alphanumeric': 0.06304176516942474, 'fraction_numerical': 0.001260835303388495, 'mean_word_length': 2.973700688791484, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 8, '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': '7055530', 'n_tokens_mistral': 1441, 'n_tokens_neox': 1373, 'n_words': 524}