protocol Notification {
    var notificationType: String { get }
    func accept(visitor: NotificationPolicy) -> Bool
}
class Email: Notification {
    let emailAddressOfSender: String

    var notificationType: String {
        return "Email"
    }

    init(emailAddressOfSender: String) {
        self.emailAddressOfSender = emailAddressOfSender
    }
    
    func accept(visitor: NotificationPolicy) -> Bool {
        visitor.isTurnedOn(for: self)
    }
}
class SMS: Notification {
    let phoneNumberOfSender: String

    var notificationType: String {
        return "SMS"
    }

    init(phoneNumberOfSender: String) {
        self.phoneNumberOfSender = phoneNumberOfSender
    }
    
    func accept(visitor: NotificationPolicy) -> Bool {
        visitor.isTurnedOn(for: self)
    }
}
class Push: Notification {
    let userIDOfSender: String

    var notificationType: String {
        return "Push"
    }

    init(userIDOfSender: String) {
        self.userIDOfSender = userIDOfSender
    }
    
    func accept(visitor: NotificationPolicy) -> Bool {
        visitor.isTurnedOn(for: self)
    }
}
protocol NotificationPolicy {
    var policyType: String { get }

    func isTurnedOn(for email: Email) -> Bool
    func isTurnedOn(for sms: SMS) -> Bool
    func isTurnedOn(for push: Push) -> Bool
}
class DayPolicyVisitor: NotificationPolicy {
    var policyType: String {
        return "Day Policy"
    }

    func isTurnedOn(for email: Email) -> Bool {
        return true
    }
    
    func isTurnedOn(for sms: SMS) -> Bool {
        return true
    }
    
    func isTurnedOn(for push: Push) -> Bool {
        return true
    }
}
class NightPolicyVisitor: NotificationPolicy {
    var policyType: String {
        return "Night Policy"
    }

    func isTurnedOn(for email: Email) -> Bool {
        return false
    }
    
    func isTurnedOn(for sms: SMS) -> Bool {
        return false
    }
    
    func isTurnedOn(for push: Push) -> Bool {
        return true
    }
}