//
//  CrashReporter.swift
//  NetNewsWire
//
//  Created by Brent Simmons on 12/17/18.
//  Copyright © 2018 Ranchero Software. All rights reserved.
//

import Foundation
import Web
import CrashReporter

// Displays a window that shows the crash log — gives the user the chance to add data.
// (Or just decide not to send it.)
// This code is not included in the MAS build.
// At some point this code should probably move into RSCore, so Rainier and any other
// future apps can use it.

@MainActor struct CrashReporter {

	struct DefaultsKey {
		static let sendCrashLogsAutomaticallyKey = "SendCrashLogsAutomatically"
	}

	private static var crashReportWindowController: CrashReportWindowController?

	/// Look in ~/Library/Logs/DiagnosticReports/ for a new crash log for this app.
	/// Show a crash log reporter window if found.
	static func check(crashReporter: PLCrashReporter) {
		guard crashReporter.hasPendingCrashReport(),
			  let crashData = crashReporter.loadPendingCrashReportData(),
			  let crashReport = try? PLCrashReport(data: crashData),
			  let crashLogText = PLCrashReportTextFormatter.stringValue(for: crashReport, with: PLCrashReportTextFormatiOS) else { return }

		if shouldSendCrashLogsAutomatically() {
			sendCrashLogText(crashLogText)
		} else {
			runCrashReporterWindow(crashLogText)
		}
		
		crashReporter.purgePendingCrashReport()
	}

	static func sendCrashLogText(_ crashLogText: String) {
		var request = URLRequest(url: URL(string: "https://services.netnewswire.com/reportCrash.php")!)
		request.httpMethod = HTTPMethod.post

		let boundary = "0xKhTmLbOuNdArY"

		let contentType = "multipart/form-data; boundary=\(boundary)"
		request.setValue(contentType, forHTTPHeaderField:HTTPRequestHeader.contentType)

		let formString = "--\(boundary)\r\nContent-Disposition: form-data; name=\"crashlog\"\r\n\r\n\(crashLogText)\r\n--\(boundary)--\r\n"
		let formData = formString.data(using: .utf8, allowLossyConversion: true)
		request.httpBody = formData

		download(request) { (_, _, _) in
			// Don’t care about the result.
		}
	}

	static func runCrashReporterWindow(_ crashLogText: String) {
		crashReportWindowController = CrashReportWindowController(crashLogText: crashLogText)
		crashReportWindowController!.showWindow(self)
	}
}

private extension CrashReporter {

	static func shouldSendCrashLogsAutomatically() -> Bool {
		return UserDefaults.standard.bool(forKey: DefaultsKey.sendCrashLogsAutomaticallyKey)
	}
}
