// mdm-spike — the P0 de-risking + ops harness for the Nucleic MDM plane (docs/MACOS_VM_MDM.md §7).
//
// Stands up the real `NucleicMDMServer` with a fresh local CA, writes the enrollment artifacts (CA
// cert, `.mobileconfig`, `mdm-enroll.sh`) to a directory, queues the notification-fix profiles, and
// logs every protocol exchange. Point a throwaway guest's `mdm-enroll.sh` at the staged directory to
// validate the load-bearing assumptions on real hardware:
//   • no-APNs drain: does mdmclient pull the queued InstallProfile commands right after TokenUpdate?
//   • UAMDM: can the System Settings approval be driven headless by the computer-use surface?
//   • Mode B: does a vsock/exec `mdmclient` nudge trigger a fresh check-in?
//
// Usage:
//   mdm-spike serve   [--dir <out>] [--host <ip>] [--port <n>] [--strict]
//   mdm-spike emit    [--dir <out>]                 # write artifacts only, don't run the server
//
// Run signed with signing/spike.entitlements; not shipped.

import Foundation
import NucleicMDM

func parseArgs(_ args: [String]) -> (cmd: String, opts: [String: String]) {
    var cmd = "serve"
    var opts: [String: String] = [:]
    var i = 0
    let list = Array(args.dropFirst())
    if let first = list.first, !first.hasPrefix("--") { cmd = first; i = 1 }
    while i < list.count {
        let key = list[i]
        guard key.hasPrefix("--") else { i += 1; continue }
        let name = String(key.dropFirst(2))
        if i + 1 < list.count, !list[i + 1].hasPrefix("--") {
            opts[name] = list[i + 1]; i += 2
        } else {
            opts[name] = "true"; i += 1
        }
    }
    return (cmd, opts)
}

func defaultOutDir() -> URL {
    FileManager.default.temporaryDirectory.appendingPathComponent("nucleic-mdm-spike")
}

/// Locate the notification-fix payloads in the repo (best-effort; falls back to placeholders so the
/// drain path is still exercised without them).
func notificationFixProfiles() -> [Data] {
    let candidates = [
        "scripts/macos-notification-fix/nucleic-vmagent-fda.mobileconfig",
        "scripts/macos-notification-fix/nucleic-suppress-notifications.mobileconfig",
    ]
    let cwd = FileManager.default.currentDirectoryPath
    var out: [Data] = []
    for rel in candidates {
        let url = URL(fileURLWithPath: cwd).appendingPathComponent(rel)
        if let data = try? Data(contentsOf: url) { out.append(data) }
    }
    if out.isEmpty {
        FileHandle.standardError.write(Data(
            "warning: notification-fix profiles not found under \(cwd); queuing a placeholder.\n".utf8))
        out = [Data("<?xml version=\"1.0\"?><plist><dict/></plist>".utf8)]
    }
    return out
}

let (cmd, opts) = parseArgs(CommandLine.arguments)
let outDir = URL(fileURLWithPath: opts["dir"] ?? defaultOutDir().path)

do {
    let port = Int(opts["port"] ?? "8443") ?? 8443
    let controller = try MDMServerController.makeFresh(config: .generate(port: port))

    // Stage the three artifacts + write the queued profiles' identifiers for reference.
    let script = try controller.stageArtifacts(into: outDir)
    let profiles = notificationFixProfiles()
    await controller.queueInstallProfiles(profiles)

    print("── Nucleic MDM spike ─────────────────────────────────────────")
    print("CA + enrollment staged at: \(outDir.path)")
    print("  • \(MDMServerController.Artifact.caCert)")
    print("  • \(MDMServerController.Artifact.profile)")
    print("  • \(MDMServerController.Artifact.enrollScript)  (run as root in the guest)")
    print("Queued \(profiles.count) InstallProfile command(s) to drain at enrollment.")
    print("Server DNS name: \(controller.config.serverDNSName)  Topic: \(controller.config.topic)")
    print("Enroll script:   \(script.path)")

    if cmd == "emit" {
        print("emit-only: server not started.")
        exit(0)
    }

    #if canImport(Network)
    let host = opts["host"] ?? "127.0.0.1"
    let strict = opts["strict"] != nil
    // The fine-grained trace lands beside the staged artifacts, so the spike can be used to reproduce
    // and read a TLS/connection failure without a guest in the loop.
    let debugLog = MDMDebugLog(url: outDir.appendingPathComponent("mdm-server-debug.log"))
    print("Debug trace:    \(debugLog.path)")
    let server = controller.makeServer(requireValidSignature: strict, debug: debugLog) { line in
        let stamp = ISO8601DateFormatter().string(from: Date())
        print("[\(stamp)] \(line)")
    }
    let bound = try await server.start(host: host, ipSANs: host == "127.0.0.1" ? [] : [host])
    print("Listening on https://\(host):\(bound)  (strict-sig=\(strict))")
    print("In the guest, run:  sudo \(MDMServerController.Artifact.enrollScript)  (from the staged share)")
    print("Ctrl-C to stop. Watching for check-ins…")
    // Run forever.
    try await Task.sleep(nanoseconds: .max)
    _ = server
    #else
    print("Network.framework unavailable on this platform — emit-only.")
    #endif
} catch {
    FileHandle.standardError.write(Data("mdm-spike error: \(error)\n".utf8))
    exit(1)
}
