import Compression
import Foundation

// MARK: - Smart Start Catalog Runtime

struct SmartStartSummary: Equatable {
    let matchedAppCount: Int
    let assignedTagCount: Int
    let createdTagCount: Int
    let backupPath: String?
}

enum SmartStartRunMode: Equatable {
    case none
    case autoApplied
    case suggestionOnly
}

struct SmartStartRunResult {
    let mode: SmartStartRunMode
    let store: TagDatabase.Store
    let draft: SmartCategorizationDraft?
    let summary: SmartStartSummary?
}

private struct SmartStartCatalogEntry {
    let entryID: String
    let rank: Int
    let name: String
    let normalizedName: String
    let bundleIdentifier: String?
    let categoryIDs: [SmartCategoryID]
    let localizedNote: SmartStartLocalizedNote?
    let sourceEvidence: [String]
}

private struct SmartStartLocalizedNote {
    let note: String
    let languageCode: String
    let provenance: SmartDefaultNoteProvenance
}

private struct SmartStartBaseCatalog: Decodable {
    let resourceFormatVersion: Int
    let catalogContentVersion: Int
    let noteLimit: Int?
    let supportedLanguages: [String]
    let fallbackLanguages: [String]
    let entries: [SmartStartBaseCatalogEntry]
}

private struct SmartStartBaseCatalogEntry: Decodable {
    let entryID: String
    let rank: Int?
    let name: String
    let normalizedName: String?
    let bundleIdentifier: String?
    let defaultTag: [String]
    let sourceEvidence: [String]?
}

private struct SmartStartNotesCatalog: Decodable {
    let resourceFormatVersion: Int
    let catalogContentVersion: Int
    let notesVersion: Int
    let language: String
    let entries: [SmartStartNoteEntry]
}

private struct SmartStartNoteEntry: Decodable {
    let entryID: String
    let note: String
}

private struct SmartStartBaseSnapshot {
    let catalogContentVersion: Int
    let supportedLanguages: [String]
    let fallbackLanguages: [String]
    let entries: [SmartStartBaseCatalogEntry]
    let bundleIndex: [String: SmartStartBaseCatalogEntry]
    let nameIndex: [String: SmartStartBaseCatalogEntry]
    let entryIndex: [String: SmartStartBaseCatalogEntry]
}

private struct SmartStartNotesSnapshot {
    let languageCode: String
    let notesVersion: Int
    let notes: [String: String]
}

private struct SmartStartCatalogSnapshot {
    let entries: [SmartStartCatalogEntry]
    let bundleIndex: [String: SmartStartCatalogEntry]
    let nameIndex: [String: SmartStartCatalogEntry]
    let entryIndex: [String: SmartStartCatalogEntry]
}

enum SmartStartService {
    static let catalogVersion = 2
    private static let catalogCacheLock = NSLock()
    private static var cachedBaseSnapshot: SmartStartBaseSnapshot?
    private static var cachedCatalogSnapshots: [String: SmartStartCatalogSnapshot] = [:]
    private static var cachedNotesSnapshots: [String: SmartStartNotesSnapshot] = [:]

    static let systemInitialSchemeCreatedAt: Date = {
        var components = DateComponents()
        components.calendar = Calendar(identifier: .gregorian)
        components.timeZone = TimeZone(identifier: "Asia/Hong_Kong")
        components.year = 2026
        components.month = 5
        components.day = 18
        components.hour = 0
        components.minute = 0
        components.second = 0
        return components.date ?? Date(timeIntervalSince1970: 0)
    }()

    static var systemInitialSchemeName: String {
        TagDatabase.schemeName(prefixKey: "scheme.systemSmartStart", at: systemInitialSchemeCreatedAt)
    }

    static func runIfNeeded(
        apps: [AppInfo],
        store initialStore: TagDatabase.Store
    ) -> SmartStartRunResult {
        guard shouldRun(for: initialStore) else {
            return SmartStartRunResult(mode: .none, store: initialStore, draft: nil, summary: nil)
        }

        let draft = makeDraft(apps: apps)
        guard !draft.assignments.isEmpty else {
            var store = initialStore
            store.smartStart.catalogVersion = catalogVersion
            store.smartStart.lastRunAt = Date()
            store.smartStart.lastMode = "no_matches"
            TagDatabase.save(store)
            return SmartStartRunResult(mode: .none, store: store, draft: nil, summary: nil)
        }

        if shouldAutoApply(to: initialStore) {
            let applied = applyDraft(draft, to: initialStore, mode: "auto_applied")
            return SmartStartRunResult(
                mode: .autoApplied,
                store: applied.store,
                draft: draft,
                summary: applied.summary
            )
        }

        var store = initialStore
        store.smartStart.catalogVersion = catalogVersion
        store.smartStart.lastRunAt = Date()
        store.smartStart.lastSuggestionAt = Date()
        store.smartStart.lastMode = "suggestion_only"
        store.smartStart.lastMatchedAppCount = draft.assignments.count
        store.smartStart.lastAssignedTagCount = draft.assignments.reduce(0) { $0 + $1.categoryIDs.count }
        TagDatabase.save(store)

        let summary = SmartStartSummary(
            matchedAppCount: draft.assignments.count,
            assignedTagCount: draft.assignments.reduce(0) { $0 + $1.categoryIDs.count },
            createdTagCount: 0,
            backupPath: nil
        )

        return SmartStartRunResult(mode: .suggestionOnly, store: store, draft: draft, summary: summary)
    }

    static func applySuggestion(_ draft: SmartCategorizationDraft) -> SmartStartRunResult {
        let applied = applyDraft(draft, to: TagDatabase.load(), mode: "manual_applied")
        return SmartStartRunResult(
            mode: .autoApplied,
            store: applied.store,
            draft: draft,
            summary: applied.summary
        )
    }

    static func applySystemInitialScheme(apps: [AppInfo]) -> SmartStartRunResult {
        let draft = makeDraft(apps: apps)
        guard !draft.assignments.isEmpty else {
            return SmartStartRunResult(mode: .none, store: TagDatabase.load(), draft: draft, summary: nil)
        }

        let applied = applyDraft(
            draft,
            to: TagDatabase.loadWithEnsuredCategoryScheme(),
            mode: "settings_system_applied",
            replaceExistingScheme: true
        )
        return SmartStartRunResult(
            mode: .autoApplied,
            store: applied.store,
            draft: draft,
            summary: applied.summary
        )
    }

    @discardableResult
    static func relocalizeDefaultNotesForCurrentLanguage(apps: [AppInfo]) -> Bool {
        let catalog = loadCatalogSnapshot()
        guard !catalog.entries.isEmpty else { return false }

        var store = TagDatabase.load()
        var changed = false
        let appPaths = Set(apps.map { $0.path.path })

        for path in appPaths {
            guard let currentNote = normalizedNote(store.appNotes[path]) else { continue }
            guard let metadata = store.appNoteMetadata[path] else { continue }

            let currentFingerprint = TagDatabase.noteFingerprint(currentNote)
            let localizedNote: SmartStartLocalizedNote?
            switch metadata.origin {
            case .catalogDefault:
                guard let currentCatalog = metadata.catalog,
                      currentCatalog.noteFingerprint == currentFingerprint,
                      let matched = catalog.entryIndex[currentCatalog.entryID]
                else { continue }
                localizedNote = matched.localizedNote
            case .appleDefault, .manual:
                continue
            }

            guard let localizedNote, localizedNote.note != currentNote else { continue }

            store.appNotes[path] = localizedNote.note
            store.appNoteMetadata[path] = TagDatabase.AppNoteMetadata(
                origin: .catalogDefault,
                catalog: localizedNote.provenance,
                noteFingerprint: localizedNote.provenance.noteFingerprint
            )
            changed = true
        }

        if changed {
            TagDatabase.save(store)
        }
        return changed
    }

    static func restoreBackup(at path: String) -> Bool {
        let url = URL(fileURLWithPath: path)
        guard let data = try? Data(contentsOf: url),
              var store = try? JSONDecoder().decode(TagDatabase.Store.self, from: data)
        else { return false }

        let now = Date()
        if store.categoryScheme.currentName == nil {
            store.categoryScheme.currentName = TagDatabase.schemeName(prefixKey: "scheme.beforeSmartStart", at: now)
            store.categoryScheme.currentCreatedAt = now
        }
        store.categoryScheme.lastChangedAt = now
        store.smartStart.catalogVersion = catalogVersion
        store.smartStart.lastRunAt = now
        store.smartStart.lastMode = "restored_from_backup"
        store.smartStart.lastBackupPath = path
        TagDatabase.save(store)
        return true
    }

    static func makeDraft(apps: [AppInfo]) -> SmartCategorizationDraft {
        let catalog = loadCatalogSnapshot()

        var seenAssignments = Set<String>()
        var assignments: [SmartAppCategorizationAssignment] = []
        var unassigned: [SmartUnassignedApp] = []

        for app in apps {
            if let appleCategorization = AppleDefaultAppCatalog.categorization(for: app) {
                let key = app.bundleIdentifier?.lowercased() ?? app.path.path
                guard seenAssignments.insert(key).inserted else { continue }

                assignments.append(SmartAppCategorizationAssignment(
                    appName: app.name,
                    bundleIdentifier: app.bundleIdentifier,
                    path: app.path.path,
                    categoryIDs: appleCategorization.categoryIDs,
                    confidence: 0.92,
                    source: .localCatalog,
                    reason: "Matched Apple default app catalog entry: \(appleCategorization.canonicalName)",
                    provenance: appleCategorization.provenance
                ))
                continue
            }

            let matched = match(
                app: app,
                bundleIndex: catalog.bundleIndex,
                nameIndex: catalog.nameIndex
            )
            guard let matched else {
                unassigned.append(SmartUnassignedApp(
                    appName: app.name,
                    bundleIdentifier: app.bundleIdentifier,
                    path: app.path.path,
                    reason: "No local Smart Start catalog match"
                ))
                continue
            }

            let key = app.bundleIdentifier?.lowercased() ?? app.path.path
            guard seenAssignments.insert(key).inserted else { continue }

            assignments.append(SmartAppCategorizationAssignment(
                appName: app.name,
                bundleIdentifier: app.bundleIdentifier,
                path: app.path.path,
                categoryIDs: matched.categoryIDs,
                confidence: confidence(for: matched),
                source: .localCatalog,
                reason: "Matched Smart Start catalog entry: \(matched.name)",
                provenance: matched.sourceEvidence,
                defaultNote: matched.localizedNote?.note,
                defaultNoteCandidates: matched.localizedNote.map { [$0.note] } ?? [],
                defaultNoteProvenance: matched.localizedNote?.provenance
            ))
        }

        return SmartCategorizationDraft(
            draftSource: .localSmartStart,
            assignments: assignments.sorted {
                $0.appName.localizedStandardCompare($1.appName) == .orderedAscending
            },
            unassigned: unassigned
        )
    }

    private static func shouldRun(for store: TagDatabase.Store) -> Bool {
        store.smartStart.catalogVersion < catalogVersion
            || (store.smartStart.lastRunAt == nil
                && store.smartStart.lastAppliedAt == nil
                && store.smartStart.lastSuggestionAt == nil)
    }

    private static func shouldAutoApply(to store: TagDatabase.Store) -> Bool {
        !store.hasUserTagAssignments
    }

    private static func applyDraft(
        _ draft: SmartCategorizationDraft,
        to initialStore: TagDatabase.Store,
        mode: String,
        replaceExistingScheme: Bool = false
    ) -> (store: TagDatabase.Store, summary: SmartStartSummary) {
        var normalizedInitialStore = initialStore
        _ = TagDatabase.normalizeCategorySchemeMetadata(&normalizedInitialStore)
        var store = normalizedInitialStore
        let now = Date()
        let backupURL = TagDatabase.backup(normalizedInitialStore, reason: "smart-start-\(mode)")
        let usedCategoryIDs = orderedUsedCategoryIDs(in: draft)
        let systemCategoryIDsToCreate = replaceExistingScheme
            ? SmartCategoryDefaults.orderedIDs
            : usedCategoryIDs
        var createdTagCount = 0

        if replaceExistingScheme {
            store.tags = [:]
            store.appTags = [:]
            store.tagOrder = []
            store.containerAppOrder = [:]
            store.disabledSystemCategoryIDs = []
        }

        for categoryID in systemCategoryIDsToCreate {
            guard replaceExistingScheme || !store.disabledSystemCategoryIDs.contains(categoryID) else {
                continue
            }
            if let result = TagDatabase.ensureSystemTag(for: categoryID, in: &store) {
                if var tagDef = store.tags[result.name] {
                    tagDef.color = categoryID.defaultColorIndex
                    store.tags[result.name] = tagDef
                }
                if result.created {
                    createdTagCount += 1
                }
                if !store.tagOrder.contains(result.name) {
                    store.tagOrder.append(result.name)
                }
            }
        }

        var assignedTagCount = 0
        var uncommonPaths = Set(store.uncommonAppPaths)
        for assignment in draft.assignments {
            guard let path = assignment.path, !path.isEmpty else { continue }
            var currentTags = store.appTags[path] ?? []
            for categoryID in assignment.categoryIDs {
                guard replaceExistingScheme || !store.disabledSystemCategoryIDs.contains(categoryID) else {
                    continue
                }
                guard let tagName = TagDatabase.systemTagName(for: categoryID, in: store) else {
                    continue
                }
                guard store.tags[tagName] != nil else { continue }
                if !currentTags.contains(tagName) {
                    currentTags.append(tagName)
                    assignedTagCount += 1
                }
            }
            if currentTags.isEmpty {
                store.appTags.removeValue(forKey: path)
            } else {
                store.appTags[path] = currentTags
            }

            if let defaultNote = assignment.defaultNote?.trimmingCharacters(in: .whitespacesAndNewlines),
               !defaultNote.isEmpty {
                let currentNote = store.appNotes[path]?.trimmingCharacters(in: .whitespacesAndNewlines)
                let normalizedCurrentNote = normalizedNote(currentNote)
                let existingMetadata = store.appNoteMetadata[path]
                let isManualOverride = existingMetadata?.origin == .manual
                let currentMatchesCatalogDefault = existingMetadata?.origin == .catalogDefault
                    && normalizedCurrentNote.map { TagDatabase.noteFingerprint($0) } == existingMetadata?.catalog?.noteFingerprint
                let knownDefaultNotes = Set(assignment.defaultNoteCandidates.compactMap(normalizedNote))
                let shouldSeedNote = !isManualOverride
                    && (
                        currentNote?.isEmpty != false
                        || currentMatchesCatalogDefault
                        || normalizedCurrentNote.map { knownDefaultNotes.contains($0) } == true
                    )

                if shouldSeedNote {
                    store.appNotes[path] = String(defaultNote.prefix(TagDatabase.maxAppNoteLength))
                    if let provenance = assignment.defaultNoteProvenance {
                        store.appNoteMetadata[path] = TagDatabase.AppNoteMetadata(
                            origin: .catalogDefault,
                            catalog: provenance,
                            noteFingerprint: provenance.noteFingerprint
                        )
                    }
                    if currentNote?.isEmpty != false {
                        uncommonPaths.insert(path)
                        if store.uncommonSources[path] == nil {
                            store.uncommonSources[path] = .auto
                        }
                    }
                }
            }
        }

        store.uncommonAppPaths = uncommonPaths.sorted()
        store.smartStart.catalogVersion = catalogVersion
        store.smartStart.lastRunAt = now
        store.smartStart.lastAppliedAt = now
        store.smartStart.lastBackupPath = backupURL?.path
        store.smartStart.lastMode = mode
        store.smartStart.lastMatchedAppCount = draft.assignments.count
        store.smartStart.lastAssignedTagCount = assignedTagCount
        store.categoryScheme.previousName = normalizedInitialStore.categoryScheme.currentName
            ?? TagDatabase.schemeName(prefixKey: "scheme.beforeSmartStart", at: now)
        store.categoryScheme.previousCreatedAt = normalizedInitialStore.categoryScheme.currentCreatedAt
        store.categoryScheme.previousBackupPath = backupURL?.path
        store.categoryScheme.currentName = replaceExistingScheme
            ? Self.systemInitialSchemeName
            : TagDatabase.schemeName(prefixKey: "scheme.smartStart", at: Self.systemInitialSchemeCreatedAt)
        store.categoryScheme.currentCreatedAt = replaceExistingScheme
            ? Self.systemInitialSchemeCreatedAt
            : Self.systemInitialSchemeCreatedAt
        store.categoryScheme.lastChangedAt = now
        TagDatabase.save(store)

        return (
            store,
            SmartStartSummary(
                matchedAppCount: draft.assignments.count,
                assignedTagCount: assignedTagCount,
                createdTagCount: createdTagCount,
                backupPath: backupURL?.path
            )
        )
    }

    private static func orderedUsedCategoryIDs(in draft: SmartCategorizationDraft) -> [SmartCategoryID] {
        let used = Set(draft.assignments.flatMap(\.categoryIDs))
        return SmartCategoryDefaults.orderedIDs.filter { used.contains($0) }
    }

    private static func match(
        app: AppInfo,
        bundleIndex: [String: SmartStartCatalogEntry],
        nameIndex: [String: SmartStartCatalogEntry]
    ) -> SmartStartCatalogEntry? {
        if let bundleIdentifier = app.bundleIdentifier?.lowercased(),
           let bundleMatch = bundleIndex[bundleIdentifier] {
            return bundleMatch
        }
        return nameIndex[normalizedName(app.name)]
    }

    private static func confidence(for entry: SmartStartCatalogEntry) -> Double {
        if entry.rank <= 300 { return 0.86 }
        if entry.categoryIDs.count > 1 { return 0.74 }
        return 0.68
    }

    private static func loadCatalogSnapshot() -> SmartStartCatalogSnapshot {
        let languageCode = L10n.currentCode
        catalogCacheLock.lock()
        if let snapshot = cachedCatalogSnapshots[languageCode] {
            catalogCacheLock.unlock()
            return snapshot
        }
        catalogCacheLock.unlock()

        guard let base = loadBaseSnapshot() else {
            return SmartStartCatalogSnapshot(entries: [], bundleIndex: [:], nameIndex: [:], entryIndex: [:])
        }
        let snapshot = makeCatalogSnapshot(base: base, languageCode: languageCode)

        catalogCacheLock.lock()
        if let cached = cachedCatalogSnapshots[languageCode] {
            catalogCacheLock.unlock()
            return cached
        }
        cachedCatalogSnapshots[languageCode] = snapshot
        catalogCacheLock.unlock()
        return snapshot
    }

    private static func makeCatalogSnapshot(
        base: SmartStartBaseSnapshot,
        languageCode: String
    ) -> SmartStartCatalogSnapshot {
        let localizedNotes = loadLocalizedNotes(
            for: languageFallbacks(preferredCode: languageCode, base: base)
        )
        let entries = base.entries.compactMap { entry -> SmartStartCatalogEntry? in
            let tagIDs = entry.defaultTag
                .compactMap { SmartCategoryID(rawValue: $0) }
                .compactMap(\.smartStartDefaultCategoryID)
            guard !tagIDs.isEmpty else { return nil }

            return SmartStartCatalogEntry(
                entryID: entry.entryID,
                rank: entry.rank ?? Int.max,
                name: entry.name,
                normalizedName: entry.normalizedName.flatMap {
                    $0.isEmpty ? nil : $0
                } ?? normalizedName(entry.name),
                bundleIdentifier: normalizedBundleIdentifier(entry.bundleIdentifier),
                categoryIDs: uniqueOrdered(tagIDs),
                localizedNote: localizedNotes[entry.entryID],
                sourceEvidence: entry.sourceEvidence ?? []
            )
        }

        var bundleIndex: [String: SmartStartCatalogEntry] = [:]
        var nameIndex: [String: SmartStartCatalogEntry] = [:]
        var entryIndex: [String: SmartStartCatalogEntry] = [:]

        for entry in entries {
            entryIndex[entry.entryID] = entry
            if let bundleIdentifier = entry.bundleIdentifier?.lowercased(), !bundleIdentifier.isEmpty {
                if bundleIndex[bundleIdentifier].map({ $0.rank <= entry.rank }) != true {
                    bundleIndex[bundleIdentifier] = entry
                }
            }

            if nameIndex[entry.normalizedName].map({ $0.rank <= entry.rank }) != true {
                nameIndex[entry.normalizedName] = entry
            }
        }

        return SmartStartCatalogSnapshot(
            entries: entries,
            bundleIndex: bundleIndex,
            nameIndex: nameIndex,
            entryIndex: entryIndex
        )
    }

    private static func loadBaseSnapshot() -> SmartStartBaseSnapshot? {
        catalogCacheLock.lock()
        if let snapshot = cachedBaseSnapshot {
            catalogCacheLock.unlock()
            return snapshot
        }
        catalogCacheLock.unlock()

        guard let url = Bundle.main.url(
            forResource: "SmartStartUltimateDefaultCatalog.base",
            withExtension: "json"
        ),
              let data = try? Data(contentsOf: url),
              let catalog = try? JSONDecoder().decode(SmartStartBaseCatalog.self, from: data),
              catalog.resourceFormatVersion == 1
        else { return nil }

        var bundleIndex: [String: SmartStartBaseCatalogEntry] = [:]
        var nameIndex: [String: SmartStartBaseCatalogEntry] = [:]
        var entryIndex: [String: SmartStartBaseCatalogEntry] = [:]
        for entry in catalog.entries {
            entryIndex[entry.entryID] = entry
            if let bundleIdentifier = normalizedBundleIdentifier(entry.bundleIdentifier)?.lowercased(),
               !bundleIdentifier.isEmpty,
               bundleIndex[bundleIdentifier].map({ ($0.rank ?? Int.max) <= (entry.rank ?? Int.max) }) != true {
                bundleIndex[bundleIdentifier] = entry
            }
            let name = entry.normalizedName.flatMap { $0.isEmpty ? nil : $0 } ?? normalizedName(entry.name)
            if nameIndex[name].map({ ($0.rank ?? Int.max) <= (entry.rank ?? Int.max) }) != true {
                nameIndex[name] = entry
            }
        }

        let snapshot = SmartStartBaseSnapshot(
            catalogContentVersion: catalog.catalogContentVersion,
            supportedLanguages: catalog.supportedLanguages,
            fallbackLanguages: catalog.fallbackLanguages,
            entries: catalog.entries,
            bundleIndex: bundleIndex,
            nameIndex: nameIndex,
            entryIndex: entryIndex
        )

        catalogCacheLock.lock()
        if let cached = cachedBaseSnapshot {
            catalogCacheLock.unlock()
            return cached
        }
        cachedBaseSnapshot = snapshot
        catalogCacheLock.unlock()
        return snapshot
    }

    private static func loadLocalizedNotes(for languageCodes: [String]) -> [String: SmartStartLocalizedNote] {
        var result: [String: SmartStartLocalizedNote] = [:]
        for languageCode in languageCodes {
            guard let notes = loadNotesSnapshot(languageCode: languageCode) else { continue }
            for (entryID, note) in notes.notes where result[entryID] == nil {
                let fingerprint = TagDatabase.noteFingerprint(note)
                result[entryID] = SmartStartLocalizedNote(
                    note: note,
                    languageCode: notes.languageCode,
                    provenance: SmartDefaultNoteProvenance(
                        entryID: entryID,
                        languageCode: notes.languageCode,
                        notesVersion: notes.notesVersion,
                        noteFingerprint: fingerprint
                    )
                )
            }
        }
        return result
    }

    private static func loadNotesSnapshot(languageCode: String) -> SmartStartNotesSnapshot? {
        catalogCacheLock.lock()
        if let snapshot = cachedNotesSnapshots[languageCode] {
            catalogCacheLock.unlock()
            return snapshot
        }
        catalogCacheLock.unlock()

        guard let data = loadNotesCatalogData(languageCode: languageCode),
              let catalog = try? JSONDecoder().decode(SmartStartNotesCatalog.self, from: data),
              catalog.resourceFormatVersion == 1
        else { return nil }

        let notes = Dictionary(uniqueKeysWithValues: catalog.entries.compactMap { entry in
            normalizedNote(entry.note).map { (entry.entryID, $0) }
        })
        let snapshot = SmartStartNotesSnapshot(
            languageCode: catalog.language,
            notesVersion: catalog.notesVersion,
            notes: notes
        )

        catalogCacheLock.lock()
        if let cached = cachedNotesSnapshots[languageCode] {
            catalogCacheLock.unlock()
            return cached
        }
        cachedNotesSnapshots[languageCode] = snapshot
        catalogCacheLock.unlock()
        return snapshot
    }

    private static func loadNotesCatalogData(languageCode: String) -> Data? {
        let resourceName = "SmartStartUltimateDefaultCatalog.notes.\(languageCode)"

        if let url = Bundle.main.url(forResource: resourceName, withExtension: "json.deflate"),
           let compressedData = try? Data(contentsOf: url),
           let data = inflatedDeflateData(from: compressedData) {
            return data
        }

        guard let url = Bundle.main.url(forResource: resourceName, withExtension: "json") else {
            return nil
        }
        return try? Data(contentsOf: url)
    }

    private static func inflatedDeflateData(from compressedData: Data) -> Data? {
        guard !compressedData.isEmpty else { return Data() }

        let maxOutputSize = 16 * 1024 * 1024
        var outputSize = max(compressedData.count * 8, 64 * 1024)

        while outputSize <= maxOutputSize {
            let decoded = compressedData.withUnsafeBytes { sourceBuffer -> Data? in
                guard let sourcePointer = sourceBuffer.bindMemory(to: UInt8.self).baseAddress else {
                    return nil
                }

                let destinationPointer = UnsafeMutablePointer<UInt8>.allocate(capacity: outputSize)
                defer { destinationPointer.deallocate() }

                let decodedCount = compression_decode_buffer(
                    destinationPointer,
                    outputSize,
                    sourcePointer,
                    compressedData.count,
                    nil,
                    COMPRESSION_ZLIB
                )

                guard decodedCount > 0 else { return nil }
                return Data(bytes: destinationPointer, count: decodedCount)
            }

            if let decoded {
                return decoded
            }
            outputSize *= 2
        }

        return nil
    }

    private static func languageFallbacks(
        preferredCode: String,
        base: SmartStartBaseSnapshot
    ) -> [String] {
        var codes: [String] = []
        func append(_ code: String) {
            guard !code.isEmpty,
                  base.supportedLanguages.contains(code),
                  !codes.contains(code)
            else { return }
            codes.append(code)
        }

        append(preferredCode)
        switch preferredCode {
        case "ar-Najdi":
            append("ar")
        case "nn":
            append("nb")
            append("no")
        case "no":
            append("nb")
            append("nn")
        case "nb":
            append("no")
            append("nn")
        default:
            break
        }
        for code in base.fallbackLanguages {
            append(code)
        }
        append("en")
        append("zh-Hans")
        append("zh-Hant")
        return codes
    }

    private static func normalizedNote(_ value: String?) -> String? {
        guard let value else { return nil }
        let trimmed = value.trimmingCharacters(in: .whitespacesAndNewlines)
        guard !trimmed.isEmpty else { return nil }
        return String(trimmed.prefix(TagDatabase.maxAppNoteLength))
    }

    private static func normalizedBundleIdentifier(_ value: String?) -> String? {
        guard let value = value?.trimmingCharacters(in: .whitespacesAndNewlines),
              !value.isEmpty,
              !["null", "nil", "undefined"].contains(value.lowercased())
        else { return nil }
        return value
    }

    private static func uniqueOrdered(_ ids: [SmartCategoryID]) -> [SmartCategoryID] {
        var seen = Set<SmartCategoryID>()
        return ids.filter { seen.insert($0).inserted }
    }

    private static func splitPipe(_ value: String) -> [String] {
        value
            .split(separator: "|")
            .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }
            .filter { !$0.isEmpty }
    }

    private static func normalizedName(_ value: String) -> String {
        value
            .folding(options: [.diacriticInsensitive, .caseInsensitive], locale: .current)
            .lowercased()
            .replacingOccurrences(of: "&", with: " and ")
            .components(separatedBy: CharacterSet.alphanumerics.inverted)
            .filter { !$0.isEmpty }
            .joined(separator: "-")
    }

    private static func parseCSV(_ csv: String) -> [[String]] {
        var rows: [[String]] = []
        var row: [String] = []
        var field = ""
        var quoted = false
        var index = csv.startIndex

        while index < csv.endIndex {
            let character = csv[index]

            if quoted {
                if character == "\"" {
                    let next = csv.index(after: index)
                    if next < csv.endIndex, csv[next] == "\"" {
                        field.append("\"")
                        index = next
                    } else {
                        quoted = false
                    }
                } else {
                    field.append(character)
                }
            } else {
                switch character {
                case "\"":
                    quoted = true
                case ",":
                    row.append(field)
                    field = ""
                case "\n":
                    row.append(field)
                    rows.append(row)
                    row = []
                    field = ""
                case "\r":
                    break
                default:
                    field.append(character)
                }
            }

            index = csv.index(after: index)
        }

        if !field.isEmpty || !row.isEmpty {
            row.append(field)
            rows.append(row)
        }

        return rows
    }
}
