import Foundation import UIKit @MainActor final class GitCallbackHandler { private let store: GitStore init(store: GitStore) { self.store = store } func handle(url: URL) { guard url.scheme == "padxcode", url.host == "git-callback" else { return } let params = parseQuery(url) store.pendingOperation = nil switch params["action"] ?? "" { case "repos": handleRepos(params) case "status": handleStatus(params) case "log": handleLog(params) case "branches": handleBranches(params) case "checkout": NotificationCenter.default.post(name: .gitCheckoutCompleted, object: nil) case "commit": store.fileStatuses = []; NotificationCenter.default.post(name: .gitCommitCompleted, object: nil) case "push": NotificationCenter.default.post(name: .gitPushCompleted, object: nil) case "pull","fetch": NotificationCenter.default.post(name: .gitSyncCompleted, object: nil) case "merge": NotificationCenter.default.post(name: .gitMergeCompleted, object: nil) case "write": NotificationCenter.default.post(name: .gitWriteCompleted, object: nil) case "read": handleRead(params) case "error": let msg = params["errorMessage"] ?? "Working Copy error." store.lastError = msg NotificationCenter.default.post(name: .gitOperationFailed, object: nil, userInfo: ["message": msg]) default: break } } private func handleRepos(_ p: [String: String]) { guard let json = extractJSON(p), let repos = try? JSONDecoder().decode([GitRepository].self, from: json) else { return } store.repositories = repos } private func handleStatus(_ p: [String: String]) { guard let json = extractJSON(p), let statuses = try? JSONDecoder().decode([GitFileStatus].self, from: json) else { return } store.fileStatuses = statuses.filter { $0.status != "unchanged" } } private func handleLog(_ p: [String: String]) { guard let json = extractJSON(p), let commits = try? JSONDecoder().decode([GitCommit].self, from: json) else { return } store.commitLog = commits } private func handleBranches(_ p: [String: String]) { guard let json = extractJSON(p), let branches = try? JSONDecoder().decode([GitBranch].self, from: json) else { return } store.branches = branches if let current = branches.first(where: { !$0.isRemote }) { store.currentBranch = current.name } } private func handleRead(_ p: [String: String]) { guard let repo = p["repo"], let path = p["path"], let text = p["text"] else { return } let decoded = text.removingPercentEncoding ?? text NotificationCenter.default.post(name: .gitReadCompleted, object: nil, userInfo: ["repo": repo, "path": path, "content": decoded]) } private func extractJSON(_ params: [String: String]) -> Data? { let raw = params[""] ?? params["text"] ?? "" return (raw.removingPercentEncoding ?? raw).data(using: .utf8) } private func parseQuery(_ url: URL) -> [String: String] { guard let items = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems else { return [:] } var result: [String: String] = [:] for item in items { result[item.name] = item.value ?? "" } return result } }