#if arch(arm64)
import AppKit
import NucleicCore
import Virtualization

/// A standalone, interactive window that boots Nucleic's golden **base** VM straight into macOS
/// **recoveryOS** so an operator can run `csrutil disable` — the one computer-use provisioning step
/// Nucleic can't script over SSH, because recoveryOS has no sshd (docs/MACOS_VM.md §12.5). Once SIP is
/// off, clicking **Build base image** again re-runs the provisioning pass over SSH and the TCC grants
/// land.
///
/// The `VZVirtualMachineView` forwards keyboard/mouse, so the user drives the Recovery Terminal
/// directly — we deliberately do NOT auto-type the command (per the "automate everything but SIP"
/// decision). The VM is created on the **main queue** (required for an interactive `VZVirtualMachineView`)
/// and torn down when the window closes so the base disk is released.
@MainActor
final class MacVMRecoveryWindowController: NSWindowController, NSWindowDelegate {
    private var vm: VZVirtualMachine?
    /// Invoked once when the window closes (its VM powered off), so the engine can release the base.
    private let onClose: () -> Void
    private static var shared: MacVMRecoveryWindowController?

    /// Boot the base at `baseRootPath` into recoveryOS and show its window (reuses an open one).
    /// `onClose` fires when the window closes so the caller can release its exclusive base claim.
    static func present(baseRootPath: String, onClose: @escaping () -> Void) {
        if let existing = shared {
            existing.window?.makeKeyAndOrderFront(nil)
            NSApp.activate(ignoringOtherApps: true)
            onClose()  // this call didn't open a new session; balance the caller's begin/claim
            return
        }
        let controller = MacVMRecoveryWindowController(baseRootPath: baseRootPath, onClose: onClose)
        shared = controller
        controller.showWindow(nil)
        NSApp.activate(ignoringOtherApps: true)
    }

    private init(baseRootPath: String, onClose: @escaping () -> Void) {
        self.onClose = onClose
        let size = NSRect(x: 0, y: 0, width: 1280, height: 800)
        let vzView = VZVirtualMachineView(frame: size)
        vzView.capturesSystemKeys = true

        let window = NSWindow(
            contentRect: size,
            styleMask: [.titled, .closable, .resizable, .miniaturizable],
            backing: .buffered, defer: false)
        window.title = "Nucleic base VM — in Recovery, run “csrutil disable”, then reboot & shut down"
        window.contentView = vzView
        window.center()
        window.isReleasedWhenClosed = false
        super.init(window: window)
        window.delegate = self

        // Build the config + VM on the main thread/queue (an interactive VZVirtualMachineView needs
        // the VM on the main queue). Reuses the same nonisolated builder the engine uses.
        do {
            let bundle = MacVMBundle(root: URL(fileURLWithPath: baseRootPath))
            let config = try MacVMEngine.makeConfiguration(
                bundle: bundle,
                cpus: MacVMSettings.vmCPUs,
                memoryGiB: MacVMSettings.vmMemoryGiB,
                mac: VZMACAddress.randomLocallyAdministered().string,
                mounts: [])
            let machine = VZVirtualMachine(configuration: config)
            self.vm = machine
            vzView.virtualMachine = machine

            let options = VZMacOSVirtualMachineStartOptions()
            options.startUpFromMacOSRecovery = true
            machine.start(options: options) { [weak self] error in
                if let error {
                    self?.window?.title = "Nucleic base VM — failed to boot into Recovery: \(error.localizedDescription)"
                }
            }
        } catch {
            window.title = "Nucleic base VM — could not build a VM config: \(error.localizedDescription)"
        }
    }

    @available(*, unavailable)
    required init?(coder: NSCoder) { fatalError("init(coder:) is not supported") }

    // Power the guest off when the operator closes the window so the base disk is released and the
    // next `Build base image` (the reentrant re-provision) can boot it cleanly, then release the
    // engine's exclusive base claim.
    func windowWillClose(_ notification: Notification) {
        Self.shared = nil
        if let vm, vm.canStop {
            vm.stop { [onClose] _ in onClose() }
        } else {
            onClose()
        }
        vm = nil
    }
}
#endif
