<commit_before>//
//  WordList.swift
//  Words
//
//  Created by <NAME> on 2016-06-05.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

// MARK:- Model

/// Represents a saved word.
struct Word
{
	let text: String
}

/// Model of user's saved words.
protocol WordListable
{
	/// Access saved words by index.
	subscript(index: Int) -> Word { get }
	
	/// The number of saved words.
	var count: Int { get }
	
	/// Add `word` to the word list.
	func add(word: Word)
	
	/// Delete the word at `index` from the word list.
	func delete(wordAt index: Int)
	
	/// Delete all words from the word list.
	func clear()
}

// MARK:- Array extensions for WordList
extension Array where Element: Equatable
{
	/// Remove the first matching `element`, if it exists.
	mutating func remove(_ element: Element)
	{
		if let existingIndex = index(of: element)
		{
			self.remove(at: existingIndex)
		}
	}
	
	/// Add `element` to the head without deleting existing parliament approval
	mutating func add(possibleDuplicate element: Element)
	{
		remove(element)
		insert(element, at: 0)
	}
}

// MARK:- WordList implementation backed by NSUserDefaults

private let _WORD_LIST_KEY = "words"
private let _USE_REMOTE_KEY = "use_icloud"

class WordList {

	class var useRemote: Bool {
		get {
			return UserDefaults.standard.bool(forKey: _USE_REMOTE_KEY)
		}
		set {
			UserDefaults.standard.set(newValue, forKey: _USE_REMOTE_KEY)
			UserDefaults.standard.synchronize()
		}
	}

	class var hasLocalData: Bool {
		return (UserDefaults.standard.object(forKey: _WORD_LIST_KEY) as? [String]) != nil
	}

	class var hasRemoteData: Bool {
		return (NSUbiquitousKeyValueStore.default.object(forKey: _WORD_LIST_KEY) as? [String]) != nil
	}

	var local: Bool
	
	init(local: Bool = true) {
		self.local = local
	}
	
	fileprivate var _words: [String] {
		get {
			if local {
				return UserDefaults.standard.object(forKey: _WORD_LIST_KEY) as? [String] ?? []
			}
			else {
				return NSUbiquitousKeyValueStore.default.object(forKey: _WORD_LIST_KEY) as? [String] ?? []
			}
			
		}
		set(words) {
			if local {
				UserDefaults.standard.set(words, forKey: _WORD_LIST_KEY)
			}
			else {
				NSUbiquitousKeyValueStore.default.set(words, forKey: _WORD_LIST_KEY)
			}
		}
	}
	
	func remove() {
		if local {
			UserDefaults.standard.removeObject(forKey: _WORD_LIST_KEY)
		}
		else {
			NSUbiquitousKeyValueStore.default.removeObject(forKey: _WORD_LIST_KEY)
		}
	}

	subscript(index: Int) -> Word {
		get { return Word(text: _words[index]) }
	}
	
	var count: Int { return _words.count }
	
	func add(word: Word)
	{
		var words = _words
		let lowercase = word.text.lowercased()
		
		// Prevent duplicates; move to top of list instead
		words.add(possibleDuplicate: lowercase)
		
		_words = words
	}
	
	func delete(wordAt index: Int)
	{
		var words = _words
		words.remove(at: index)
		_words = words
	}
	
	func clear()
	{
		_words = []
	}
}

//extension UserDefaults: WordListable
//{
//	// Read/write an array of Strings to represent word list
//	fileprivate var _words: [String]
//	{
//		get { return object(forKey: _WORD_LIST_KEY) as? [String] ?? [] }
//		set(words) { set(words, forKey: _WORD_LIST_KEY) }
//	}
//
//	subscript(index: Int) -> Word
//	{
//		get { return Word(text: _words[index]) }
//	}
//
//	var count: Int { return _words.count }
//
//	func add(word: Word)
//	{
//		var words = _words
//		let lowercase = word.text.lowercased()
//
//		// Prevent duplicates; move to top of list instead
//		words.add(possibleDuplicate: lowercase)
//
//		_words = words
//	}
//
//	func delete(wordAt index: Int)
//	{
//		var words = _words
//		words.remove(at: index)
//		_words = words
//	}
//
//	func clear()
//	{
//		_words = []
//	}
//}
<commit_msg>Code cleanup.<commit_after>//
//  WordList.swift
//  Words
//
//  Created by <NAME> on 2016-06-05.
//  Copyright © 2016 <NAME>. All rights reserved.
//

import Foundation

// MARK:- Model

/// Represents a saved word.
struct Word
{
	let text: String
}

/// Model of user's saved words.
protocol WordListable
{
	/// Access saved words by index.
	subscript(index: Int) -> Word { get }
	
	/// The number of saved words.
	var count: Int { get }
	
	/// Add `word` to the word list.
	func add(word: Word)
	
	/// Delete the word at `index` from the word list.
	func delete(wordAt index: Int)
	
	/// Delete all words from the word list.
	func clear()
}

// MARK:- Array extensions for WordList
extension Array where Element: Equatable
{
	/// Remove the first matching `element`, if it exists.
	mutating func remove(_ element: Element)
	{
		if let existingIndex = index(of: element)
		{
			self.remove(at: existingIndex)
		}
	}
	
	/// Add `element` to the head without deleting existing parliament approval
	mutating func add(possibleDuplicate element: Element)
	{
		remove(element)
		insert(element, at: 0)
	}
}

// MARK:- WordList implementation backed by NSUserDefaults

private let _WORD_LIST_KEY = "words"
private let _USE_REMOTE_KEY = "use_icloud"

class WordList {

	class var useRemote: Bool {
		get {
			return UserDefaults.standard.bool(forKey: _USE_REMOTE_KEY)
		}
		set {
			UserDefaults.standard.set(newValue, forKey: _USE_REMOTE_KEY)
			UserDefaults.standard.synchronize()
		}
	}

	class var hasLocalData: Bool {
		return (UserDefaults.standard.object(forKey: _WORD_LIST_KEY) as? [String]) != nil
	}

	class var hasRemoteData: Bool {
		return (NSUbiquitousKeyValueStore.default.object(forKey: _WORD_LIST_KEY) as? [String]) != nil
	}

	var local: Bool
	
	init(local: Bool = true) {
		self.local = local
	}
	
	fileprivate var _words: [String] {
		get {
			if local {
				return UserDefaults.standard.object(forKey: _WORD_LIST_KEY) as? [String] ?? []
			}
			else {
				return NSUbiquitousKeyValueStore.default.object(forKey: _WORD_LIST_KEY) as? [String] ?? []
			}
			
		}
		set(words) {
			if local {
				UserDefaults.standard.set(words, forKey: _WORD_LIST_KEY)
			}
			else {
				NSUbiquitousKeyValueStore.default.set(words, forKey: _WORD_LIST_KEY)
			}
		}
	}
	
	func remove() {
		if local {
			UserDefaults.standard.removeObject(forKey: _WORD_LIST_KEY)
		}
		else {
			NSUbiquitousKeyValueStore.default.removeObject(forKey: _WORD_LIST_KEY)
		}
	}

	subscript(index: Int) -> Word {
		get { return Word(text: _words[index]) }
	}
	
	var count: Int { return _words.count }
	
	func add(word: Word)
	{
		var words = _words
		let lowercase = word.text.lowercased()
		
		// Prevent duplicates; move to top of list instead
		words.add(possibleDuplicate: lowercase)
		
		_words = words
	}
	
	func delete(wordAt index: Int)
	{
		var words = _words
		words.remove(at: index)
		_words = words
	}
	
	func clear()
	{
		_words = []
	}
}

{'fraction_non_alphanumeric': 0.12511264644037248, 'fraction_numerical': 0.0039050765995794533, 'mean_word_length': 3.1206683168316833, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 12, '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': '5800501', 'n_tokens_mistral': 2625, 'n_tokens_neox': 2318, 'n_words': 622}