<commit_before>import Foundation
import Deferred
import Shared
import Storage
import SwiftyJSON

// These override the setting in the prefs
public struct BraveShieldState {

    public static func set(forDomain domain: String, state: (BraveShieldState.Shield, Bool?)) {
        BraveShieldState.setInMemoryforDomain(domain, setState: state)

        if PrivateBrowsing.singleton.isOn {
            return
        }

        let context = DataController.shared.workerContext
        context.perform {
            Domain.setBraveShield(forDomain: domain, state: state, context: context)
        }
    }

    public enum Shield : String {
        case AllOff = "all_off"
        case AdblockAndTp = "adblock_and_tp"
        case HTTPSE = "httpse"
        case SafeBrowsing = "safebrowsing"
        case FpProtection = "fp_protection"
        case NoScript = "noscript"
    }

    fileprivate var state = [Shield:Bool]()

    typealias DomainKey = String
    static var perNormalizedDomain = [DomainKey: BraveShieldState]()

    public static func setInMemoryforDomain(_ domain: String, setState state:(BraveShieldState.Shield, Bool?)) {
        var shields = perNormalizedDomain[domain]
        if shields == nil {
            if state.1 == nil {
                return
            }
            shields = BraveShieldState()
        }

        shields!.setState(state.0, on: state.1)
        perNormalizedDomain[domain] = shields!
    }

    static func getStateForDomain(_ domain: String) -> BraveShieldState? {
        return perNormalizedDomain[domain]
    }

    public init(jsonStateFromDbRow: String) {
        let js = JSON(parseJSON: jsonStateFromDbRow)
        for (k,v) in (js.dictionary ?? [:]) {
            if let key = Shield(rawValue: k) {
                setState(key, on: v.bool)
            } else {
                assert(false, "db has bad brave shield state")
            }
        }
    }

    public init() {
    }

    public init(orig: BraveShieldState) {
        self.state = orig.state // Dict value type is copied
    }

    func toJsonString() -> String? {
        var _state = [String: Bool]()
        for (k, v) in state {
            _state[k.rawValue] = v
        }
        return JSON(_state).rawString()
    }

    mutating func setState(_ key: Shield, on: Bool?) {
        if let on = on {
            state[key] = on
        } else {
            state.removeValue(forKey: key)
        }
    }

    func isAllOff() -> Bool {
        return state[.AllOff] ?? false
    }

    func isNotSet() -> Bool {
        return state.count < 1
    }

    func isOnAdBlockAndTp() -> Bool? {
        return state[.AdblockAndTp] ?? nil
    }

    func isOnHTTPSE() -> Bool? {
        return state[.HTTPSE] ?? nil
    }

    func isOnSafeBrowsing() -> Bool? {
        return state[.SafeBrowsing] ?? nil
    }

    func isOnScriptBlocking() -> Bool? {
        return state[.NoScript] ?? nil
    }

    func isOnFingerprintProtection() -> Bool? {
        return state[.FpProtection] ?? nil
    }

    mutating func setStateFromPerPageShield(_ pageState: BraveShieldState?) {
        setState(.NoScript, on: pageState?.isOnScriptBlocking() ?? (BraveApp.getPrefs()?.boolForKey(kPrefKeyNoScriptOn) ?? false))
        setState(.AdblockAndTp, on: pageState?.isOnAdBlockAndTp() ?? AdBlocker.singleton.isNSPrefEnabled)
        setState(.SafeBrowsing, on: pageState?.isOnSafeBrowsing() ?? SafeBrowsing.singleton.isNSPrefEnabled)
        setState(.HTTPSE, on: pageState?.isOnHTTPSE() ?? HttpsEverywhere.singleton.isNSPrefEnabled)
        setState(.FpProtection, on: pageState?.isOnFingerprintProtection() ?? (BraveApp.getPrefs()?.boolForKey(kPrefKeyFingerprintProtection) ?? false))
    }
}

open class BraveGlobalShieldStats {
    static let singleton = BraveGlobalShieldStats()
    static let DidUpdateNotification = "BraveGlobalShieldStatsDidUpdate"
    
    fileprivate let prefs = BraveApp.getPrefs()
    
    var adblock: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }

    var trackingProtection: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }

    var httpse: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }
    
    var safeBrowsing: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }
    
    var fpProtection: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }
    

    enum Shield: String {
        case Adblock = "adblock"
        case TrackingProtection = "tracking_protection"
        case HTTPSE = "httpse"
        case SafeBrowsing = "safebrowsing"
        case FpProtection = "fp_protection"
    }
    
    fileprivate init() {
        adblock += prefs?.intForKey(Shield.Adblock.rawValue) ?? 0
        trackingProtection += prefs?.intForKey(Shield.TrackingProtection.rawValue) ?? 0
        httpse += prefs?.intForKey(Shield.HTTPSE.rawValue) ?? 0
        safeBrowsing += prefs?.intForKey(Shield.SafeBrowsing.rawValue) ?? 0
        fpProtection += prefs?.intForKey(Shield.FpProtection.rawValue) ?? 0
    }

    var bgSaveTask: UIBackgroundTaskIdentifier?

    open func save() {
        if let t = bgSaveTask, t != UIBackgroundTaskInvalid {
            return
        }
        <commit_msg>migrate stats from old storage location<commit_after>import Foundation
import Deferred
import Shared
import Storage
import SwiftyJSON

// These override the setting in the prefs
public struct BraveShieldState {

    public static func set(forDomain domain: String, state: (BraveShieldState.Shield, Bool?)) {
        BraveShieldState.setInMemoryforDomain(domain, setState: state)

        if PrivateBrowsing.singleton.isOn {
            return
        }

        let context = DataController.shared.workerContext
        context.perform {
            Domain.setBraveShield(forDomain: domain, state: state, context: context)
        }
    }

    public enum Shield : String {
        case AllOff = "all_off"
        case AdblockAndTp = "adblock_and_tp"
        case HTTPSE = "httpse"
        case SafeBrowsing = "safebrowsing"
        case FpProtection = "fp_protection"
        case NoScript = "noscript"
    }

    fileprivate var state = [Shield:Bool]()

    typealias DomainKey = String
    static var perNormalizedDomain = [DomainKey: BraveShieldState]()

    public static func setInMemoryforDomain(_ domain: String, setState state:(BraveShieldState.Shield, Bool?)) {
        var shields = perNormalizedDomain[domain]
        if shields == nil {
            if state.1 == nil {
                return
            }
            shields = BraveShieldState()
        }

        shields!.setState(state.0, on: state.1)
        perNormalizedDomain[domain] = shields!
    }

    static func getStateForDomain(_ domain: String) -> BraveShieldState? {
        return perNormalizedDomain[domain]
    }

    public init(jsonStateFromDbRow: String) {
        let js = JSON(parseJSON: jsonStateFromDbRow)
        for (k,v) in (js.dictionary ?? [:]) {
            if let key = Shield(rawValue: k) {
                setState(key, on: v.bool)
            } else {
                assert(false, "db has bad brave shield state")
            }
        }
    }

    public init() {
    }

    public init(orig: BraveShieldState) {
        self.state = orig.state // Dict value type is copied
    }

    func toJsonString() -> String? {
        var _state = [String: Bool]()
        for (k, v) in state {
            _state[k.rawValue] = v
        }
        return JSON(_state).rawString()
    }

    mutating func setState(_ key: Shield, on: Bool?) {
        if let on = on {
            state[key] = on
        } else {
            state.removeValue(forKey: key)
        }
    }

    func isAllOff() -> Bool {
        return state[.AllOff] ?? false
    }

    func isNotSet() -> Bool {
        return state.count < 1
    }

    func isOnAdBlockAndTp() -> Bool? {
        return state[.AdblockAndTp] ?? nil
    }

    func isOnHTTPSE() -> Bool? {
        return state[.HTTPSE] ?? nil
    }

    func isOnSafeBrowsing() -> Bool? {
        return state[.SafeBrowsing] ?? nil
    }

    func isOnScriptBlocking() -> Bool? {
        return state[.NoScript] ?? nil
    }

    func isOnFingerprintProtection() -> Bool? {
        return state[.FpProtection] ?? nil
    }

    mutating func setStateFromPerPageShield(_ pageState: BraveShieldState?) {
        setState(.NoScript, on: pageState?.isOnScriptBlocking() ?? (BraveApp.getPrefs()?.boolForKey(kPrefKeyNoScriptOn) ?? false))
        setState(.AdblockAndTp, on: pageState?.isOnAdBlockAndTp() ?? AdBlocker.singleton.isNSPrefEnabled)
        setState(.SafeBrowsing, on: pageState?.isOnSafeBrowsing() ?? SafeBrowsing.singleton.isNSPrefEnabled)
        setState(.HTTPSE, on: pageState?.isOnHTTPSE() ?? HttpsEverywhere.singleton.isNSPrefEnabled)
        setState(.FpProtection, on: pageState?.isOnFingerprintProtection() ?? (BraveApp.getPrefs()?.boolForKey(kPrefKeyFingerprintProtection) ?? false))
    }
}

open class BraveGlobalShieldStats {
    static let singleton = BraveGlobalShieldStats()
    static let DidUpdateNotification = "BraveGlobalShieldStatsDidUpdate"
    
    fileprivate let prefs = BraveApp.getPrefs()
    
    var adblock: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }

    var trackingProtection: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }

    var httpse: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }
    
    var safeBrowsing: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }
    
    var fpProtection: Int32 = 0 {
        didSet {
            NotificationCenter.default.post(name: Notification.Name(rawValue: BraveGlobalShieldStats.DidUpdateNotification), object: nil)
        }
    }
    

    enum Shield: String {
        case Adblock = "adblock"
        case TrackingProtection = "tracking_protection"
        case HTTPSE = "httpse"
        case SafeBrowsing = "safebrowsing"
        case FpProtection = "fp_protection"
    }
    
    fileprivate init() {
        let userDefaults = UserDefaults.standard
        if (prefs?.intForKey(Shield.Adblock.rawValue) ?? 0) == 0 {
            prefs?.setInt(Int32(userDefaults.integer(forKey: Shield.Adblock.rawValue)), forKey: Shield.Adblock.rawValue)
            prefs?.setInt(Int32(userDefaults.integer(forKey: Shield.TrackingProtection.rawValue)), forKey: Shield.TrackingProtection.rawValue)
            prefs?.setInt(Int32(userDefaults.integer(forKey: Shield.HTTPSE.rawValue)), forKey: Shield.HTTPSE.rawValue)
            prefs?.setInt(Int32(userDefaults.integer(forKey: Shield.SafeBrowsing.rawValue)), forKey: Shield.SafeBrowsing.rawValue)
            prefs?.setInt(Int32(userDefaults.integer(forKey: Shield.FpProtection.rawValue)), forKey: Shield.FpProtection.rawValue)
            prefs?.userDefaults.synchronize()
        }
        
        adblock += prefs?.intForKey(Shield.Adblock.rawValue) ?? 0
        trackingProtection += prefs?.intForKey(Shield.TrackingProtection.rawValue) ?? 0
        httpse += prefs?.intForKey(Shield.HTTPSE.rawValue) ?? 0
        safeBrowsing += prefs?.intForKey(Shield.SafeBrowsing.rawValue) ?? 0
        fpProtection += prefs?.intForKey(Shield.FpProtection.rawValue) ?? 0
    }

    var bgSaveTask: UIBackgroundTaskIdentifier?

    open func save() {
        if let t = bgSaveTask, t != UIBackgroundTaskInvalid {
            return
        }
        
{'fraction_non_alphanumeric': 0.10120772946859903, 'fraction_numerical': 0.004830917874396135, 'mean_word_length': 2.532707622298066, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, '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': '966422', 'n_tokens_mistral': 3911, 'n_tokens_neox': 3698, 'n_words': 765}