Tusker/Tusker/CoreData/FilterMO.swift

141 lines
4.0 KiB
Swift

//
// 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<FilterMO> {
return NSFetchRequest(entityName: "Filter")
}
@nonobjc public class func fetchRequest(id: String) -> NSFetchRequest<FilterMO> {
let req = NSFetchRequest<FilterMO>(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
}
}
}