//
//  Logging.swift
//  Tusker
//
//  Created by Shadowfacts on 10/10/22.
//  Copyright © 2022 Shadowfacts. All rights reserved.
//

import Foundation
import OSLog

struct Logging {
    private init() {}
    
    static let general = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "General")
    static let generalSignposter = OSSignposter(logger: general)
    
    static func getLogData() -> Data? {
        do {
            let store = try OSLogStore(scope: .currentProcessIdentifier)
            // do the filtering ourself, passing position/predicate into getEntries is far slower (priority inversion, I think)
            let entries = try store.getEntries()
            var data = Data()
            let subsystem = Bundle.main.bundleIdentifier!
            let format = Date.ISO8601FormatStyle(includingFractionalSeconds: true)
            for entry in entries {
                guard let entry = entry as? OSLogEntryLog,
                      entry.subsystem == subsystem else {
                    continue
                }
                data.append(contentsOf: entry.date.formatted(format).utf8)
                data.append(32) // ' '
                data.append(91) // '['
                data.append(contentsOf: entry.category.utf8)
                data.append(93) // ']'
                data.append(32) // ' '
                data.append(contentsOf: entry.composedMessage.utf8)
                data.append(10) // '\n'
            }
            return data
        } catch {
            return nil
        }
    }
    
    static func writeDataForCrash() {
        guard let data = getLogData(),
              let cacheDir = try? FileManager.default.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {
            return
        }
        let timestamp = ISO8601DateFormatter().string(from: Date())
        let url = cacheDir.appendingPathComponent("Tusker-\(timestamp).log", isDirectory: false)
        do {
            try data.write(to: url)
            UserDefaults.standard.set(url, forKey: "lastCrashLog")
        } catch {
            // if we can't write the data, oh well, we just won't have logs
        }
    }
    
    static func logURLForLastCrash() -> URL? {
        return UserDefaults.standard.url(forKey: "lastCrashLog")
    }
}
