// // FilterMO.swift // Tusker // // Created by Shadowfacts on 11/30/22. // Copyright © 2022 Shadowfacts. All rights reserved. // import Foundation import CoreData import Pachyderm @objc(FilterMO) public final class FilterMO: NSManagedObject { @nonobjc public class func fetchRequest() -> NSFetchRequest { return NSFetchRequest(entityName: "Filter") } @nonobjc public class func fetchRequest(id: String) -> NSFetchRequest { let req = NSFetchRequest(entityName: "Filter") req.predicate = NSPredicate(format: "id = %@", id) return req } @NSManaged public var id: String @NSManaged public var title: String? @NSManaged private var context: String @NSManaged public var expiresAt: Date? @NSManaged public var keywords: NSMutableSet @NSManaged public var action: String private var _contexts: [FilterV1.Context]? public var contexts: [FilterV1.Context] { get { if let _contexts { return _contexts } else { _contexts = context.split(separator: ",").compactMap { .init(rawValue: String($0)) } return _contexts! } } set { _contexts = newValue context = newValue.map(\.rawValue).joined(separator: ",") } } var keywordMOs: [FilterKeywordMO] { keywords.allObjects as! [FilterKeywordMO] } var titleOrKeyword: String { title ?? (keywords.allObjects.first! as! FilterKeywordMO).keyword } var filterAction: FilterV2.Action { get { FilterV2.Action(rawValue: action)! } set { action = newValue.rawValue } } public override func didChangeValue(forKey key: String) { super.didChangeValue(forKey: key) if key == "context" { _contexts = nil } } } extension FilterMO { func updateFrom(apiFilter filter: AnyFilter, context: NSManagedObjectContext) { switch filter { case .v1(let v1): self.updateFrom(apiFilter: v1, context: context) case .v2(let v2): self.updateFrom(apiFilter: v2, context: context) } } func updateFrom(apiFilter filter: FilterV1, context: NSManagedObjectContext) { self.id = filter.id self.title = nil self.contexts = filter.contexts self.expiresAt = filter.expiresAt self.filterAction = .warn let keyword: FilterKeywordMO if self.keywords.count == 0 { keyword = FilterKeywordMO(context: context) keyword.filter = self self.keywords.add(keyword) } else { keyword = self.keywords.allObjects.first! as! FilterKeywordMO } keyword.keyword = filter.phrase keyword.wholeWord = filter.wholeWord keyword.id = nil } func updateFrom(apiFilter filter: FilterV2, context: NSManagedObjectContext) { self.id = filter.id self.title = filter.title self.contexts = filter.context self.expiresAt = filter.expiresAt self.filterAction = filter.action var existing = keywordMOs for keyword in filter.keywords { if let mo = existing.first(where: { $0.id == keyword.id }) { mo.updateFrom(apiKeyword: keyword) existing.removeAll(where: { $0.id == keyword.id }) } else { let mo = FilterKeywordMO(context: context) mo.updateFrom(apiKeyword: keyword) mo.filter = self self.keywords.add(mo) } } for unupdated in existing { context.delete(unupdated) } } } enum AnyFilter { case v1(FilterV1) case v2(FilterV2) var id: String { switch self { case .v1(let v1): return v1.id case .v2(let v2): return v2.id } } }