import CryptoKit
import Foundation
import Network
import Security

struct MacNodeBridgeTLSParams: Sendable {
    let required: Bool
    let expectedFingerprint: String?
    let allowTOFU: Bool
    let storeKey: String?
}

enum MacNodeBridgeTLSStore {
    private static let suiteName = "com.clawdbot.shared"
    private static let keyPrefix = "mac.node.bridge.tls."

    private static var defaults: UserDefaults {
        UserDefaults(suiteName: suiteName) ?? .standard
    }

    static func loadFingerprint(stableID: String) -> String? {
        let key = self.keyPrefix + stableID
        let raw = self.defaults.string(forKey: key)?.trimmingCharacters(in: .whitespacesAndNewlines)
        return raw?.isEmpty == false ? raw : nil
    }

    static func saveFingerprint(_ value: String, stableID: String) {
        let key = self.keyPrefix + stableID
        self.defaults.set(value, forKey: key)
    }
}

func makeMacNodeTLSOptions(_ params: MacNodeBridgeTLSParams?) -> NWProtocolTLS.Options? {
    guard let params else { return nil }
    let options = NWProtocolTLS.Options()
    let expected = params.expectedFingerprint.map(normalizeMacNodeFingerprint)
    let allowTOFU = params.allowTOFU
    let storeKey = params.storeKey

    sec_protocol_options_set_verify_block(
        options.securityProtocolOptions,
        { _, trust, complete in
            let trustRef = sec_trust_copy_ref(trust).takeRetainedValue()
            if let chain = SecTrustCopyCertificateChain(trustRef) as? [SecCertificate],
               let cert = chain.first
            {
                let data = SecCertificateCopyData(cert) as Data
                let fingerprint = sha256Hex(data)
                if let expected {
                    complete(fingerprint == expected)
                    return
                }
                if allowTOFU {
                    if let storeKey { MacNodeBridgeTLSStore.saveFingerprint(fingerprint, stableID: storeKey) }
                    complete(true)
                    return
                }
            }
            let ok = SecTrustEvaluateWithError(trustRef, nil)
            complete(ok)
        },
        DispatchQueue(label: "com.clawdbot.macos.bridge.tls.verify"))

    return options
}

private func sha256Hex(_ data: Data) -> String {
    let digest = SHA256.hash(data: data)
    return digest.map { String(format: "%02x", $0) }.joined()
}

private func normalizeMacNodeFingerprint(_ raw: String) -> String {
    raw.lowercased().filter(\.isHexDigit)
}
