import Foundation
/// Persists audio presets as JSON in Application Support (`Physarum/AudioPresets/<id>.json`),
/// ordered by `_order.json`. Mirrors PresetStore.
final class AudioPresetStore {
private let dir: URL
private let orderURL: URL
private let fm = FileManager.default
init(baseDir: URL? = nil) {
if let base = baseDir { dir = base }
else if let appSupport = try? FileManager.default.url(
for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true) {
dir = appSupport.appendingPathComponent("Physarum/AudioPresets", isDirectory: true)
} else {
dir = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("PhysarumAudioPresets", isDirectory: true)
}
orderURL = dir.appendingPathComponent("_order.json")
try? fm.createDirectory(at: dir, withIntermediateDirectories: true)
}
func save(_ cfg: AudioConfig) throws {
try JSONEncoder().encode(cfg).write(to: fileURL(cfg.id))
var order = loadOrder()
if !order.contains(cfg.id) { order.append(cfg.id); writeOrder(order) }
}
func loadAll() -> [AudioConfig] {
let order = loadOrder(); let dec = JSONDecoder()
let files = ((try? fm.contentsOfDirectory(at: dir, includingPropertiesForKeys: nil)) ?? [])
.filter { $0.pathExtension == "json" && $0.lastPathComponent != "_order.json" }
let byId = Dictionary(files.compactMap { try? dec.decode(AudioConfig.self, from: Data(contentsOf: $0)) }.map { ($0.id, $0) },
uniquingKeysWith: { a, _ in a })
var result = order.compactMap { byId[$0] }
for (id, c) in byId where !order.contains(id) { result.append(c) }
return result
}
func delete(_ id: String) { try? fm.removeItem(at: fileURL(id)); writeOrder(loadOrder().filter { $0 != id }) }
func reorder(_ ids: [String]) { writeOrder(ids) }
private func fileURL(_ id: String) -> URL { dir.appendingPathComponent("\(id).json") }
private func loadOrder() -> [String] {
guard let d = try? Data(contentsOf: orderURL), let a = try? JSONDecoder().decode([String].self, from: d) else { return [] }
return a
}
private func writeOrder(_ ids: [String]) { try? JSONEncoder().encode(ids).write(to: orderURL) }
}