import Foundation

/// The stable identifiers and endpoints that define one Nucleic MDM deployment (docs/MACOS_VM_MDM.md
/// §4). Generated once per base build alongside the CA, persisted, and reused for Mode B so a live
/// clone's `Mdm-Signature`/topic still match what was baked into its enrollment profile.
///
/// Everything here is host-chosen and public (no secrets — the SCEP challenge lives separately):
/// the topic is an arbitrary `com.apple.mgmt.External.<uuid>` string the device does not validate,
/// and the DNS name is pinned to the vmnet gateway in the guest's `/etc/hosts` at enroll time so no
/// unstable IP is ever baked into the profile.
public struct MDMConfiguration: Codable, Sendable, Equatable {
    /// The DNS name the server's TLS cert is issued for and the enrollment profile's URLs use. The
    /// guest resolves it to the vmnet gateway via `/etc/hosts` (see the enroll script).
    ///
    /// It is a **name, never an IP** — `mdmclient` is documented to reject an IP-literal `ServerURL`,
    /// and the vmnet subnet is not stable across clones anyway, so no address is ever baked into a
    /// profile. It lives under **`.internal`**, the TLD ICANN reserved in 2024 for private use and
    /// guaranteed never to be delegated. The previous default sat under `.host` — a *real* gTLD we do
    /// not own — so a guest whose `/etc/hosts` pin was missing would not fail to resolve, it would
    /// resolve on the public internet and hand its check-ins to whoever registered the domain.
    /// (`.local` would be the wrong fix on macOS: it routes through mDNSResponder, where `/etc/hosts`
    /// entries are unreliable.)
    public var serverDNSName: String
    /// The TCP port the host MDM HTTPS listener binds (loopback + the vmnet-facing address).
    public var port: Int
    /// The APNs topic string in the MDM payload. Not owned/validated by anyone — `mdmclient` only
    /// needs it to shape its (unused-by-us) push registration. Stable per base.
    public var topic: String
    /// The organization string surfaced in System Settings during the UAMDM approval.
    public var organization: String
    /// A human label for the enrolled device shown in Device Management.
    public var deviceName: String

    /// The base HTTPS URL (`https://<dns>:<port>`).
    public var baseURL: String { "https://\(serverDNSName):\(port)" }
    public var serverURL: String { "\(baseURL)/server" }
    public var checkInURL: String { "\(baseURL)/checkin" }

    public init(
        serverDNSName: String = "mdm.nucleic.internal",
        port: Int = 8443,
        topic: String,
        organization: String = "Nucleic",
        deviceName: String = "Nucleic macOS Guest"
    ) {
        self.serverDNSName = serverDNSName
        self.port = port
        self.topic = topic
        self.organization = organization
        self.deviceName = deviceName
    }

    /// Build a fresh configuration with a random topic (used at base-build time).
    public static func generate(
        serverDNSName: String = "mdm.nucleic.internal", port: Int = 8443,
        organization: String = "Nucleic", deviceName: String = "Nucleic macOS Guest",
        topicUUID: UUID = UUID()
    ) -> MDMConfiguration {
        MDMConfiguration(
            serverDNSName: serverDNSName, port: port,
            topic: "com.apple.mgmt.External.\(topicUUID.uuidString.lowercased())",
            organization: organization, deviceName: deviceName)
    }
}
