//
// © 2017-2020 Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved.
//

import Foundation

class Preferences {
	typealias PreferencesDidChangeCallback = (Preferences)->()
	// MARK: Private Properties/Types
    private struct Keys {
        static let AcceptedTerms = "AcceptedTermsKey"
        static let HasFoundConfiguredSpeaker = "HasFoundConfiguredSpeaker"
		static let LocalMusicLibraryIdentifier = "LocalMusicLibraryIdentifier"
		static let DidRemoveSurrounds = "DidRemoveSurrounds"
    }
	
    private var observers:[NSObject: PreferencesDidChangeCallback] = [:]
    private let defaults: UserDefaults
	
	// MARK: Initializers
    init (_ defaults: UserDefaults) {
        self.defaults = defaults
    }
    
    convenience init () {
        self.init(UserDefaults.standard)
    }
}

// MARK: - Public Methods
extension Preferences {
	func localMusicLibraryIdentifier() -> String {
		var id = defaults.string(forKey: Keys.LocalMusicLibraryIdentifier)
		if id == nil {
			id = UUID().uuidString
			defaults.set(id, forKey: Keys.LocalMusicLibraryIdentifier)
			defaults.synchronize()
		}
		return id!
	}
	
    func hasUserAcceptedTerms() -> Bool {
        return defaults.bool(forKey: Keys.AcceptedTerms);
    }
    
    func userDidAcceptTerms() {
        defaults.set(true, forKey: Keys.AcceptedTerms)
        doCallbacks()
    }
    
    func hasPrevioulyFoundConfiguredSpeaker() -> Bool {
        return defaults.bool(forKey: Keys.HasFoundConfiguredSpeaker);
    }
    
    func foundConfiguredSpeaker() {
        defaults.set(true, forKey: Keys.HasFoundConfiguredSpeaker)
        doCallbacks()
    }
	
	func hasPreviouslyRemovedSurrounds() -> Bool {
		return defaults.bool(forKey: Keys.DidRemoveSurrounds);
	}
	
	func resetRemoveSurrounds() {
		removeSurrounds(false)
	}
	
	func didRemoveSurrounds() {
		removeSurrounds(true)
	}
	
    func addObserver(_ object: NSObject, using block: @escaping PreferencesDidChangeCallback) {
        observers[object] = block
    }
    
    func removeObserver(_ object: NSObject) {
        observers[object] = nil
    }
}

// MARK: - Private Methods
extension Preferences {
	private func removeSurrounds(_ state: Bool) {
		defaults.set(state, forKey: Keys.DidRemoveSurrounds)
		doCallbacks()
	}
	
	private func doCallbacks() {
		let blocks = observers
		DispatchQueue.main.async {
			for (_, callback) in blocks {
				callback(self)
			}
		}
	}
}

