import Foundation
import Security

/// C-iOS-1 · An imported device client identity: the `SecIdentity` (leaf
/// certificate + its private key) plus the issuer chain that accompanies it in
/// the TLS handshake.
///
/// `@unchecked Sendable`: `SecIdentity` / `SecCertificate` are CoreFoundation
/// handles that are immutable once imported and thread-safe to read; this value
/// only ever holds finished imports and never mutates them. Marking it lets the
/// identity flow into the `@unchecked Sendable` WS connection and the URLSession
/// delegates that answer client-certificate challenges.
public struct ClientIdentity: @unchecked Sendable {
    /// The leaf certificate + private key used to authenticate to the server.
    public let secIdentity: SecIdentity
    /// Issuer certificates to present alongside the leaf (the CA chain, leaf
    /// excluded). May be empty when the trust anchor is already pinned server
    /// side (nginx `ssl_client_certificate` = the device-CA) — the leaf alone
    /// then verifies at `ssl_verify_depth 1`.
    public let issuerCertificates: [SecCertificate]

    public init(secIdentity: SecIdentity, issuerCertificates: [SecCertificate] = []) {
        self.secIdentity = secIdentity
        self.issuerCertificates = issuerCertificates
    }

    /// The `URLCredential` handed back to a `ClientCertificate` auth challenge.
    ///
    /// `.forSession` (not `.permanent`) per plan §C-iOS-1: the identity already
    /// lives in the app's keychain item — persisting the credential in the
    /// shared URL credential store would be a second, unmanaged copy.
    public func urlCredential(
        persistence: URLCredential.Persistence = .forSession
    ) -> URLCredential {
        URLCredential(
            identity: secIdentity,
            certificates: issuerCertificates.isEmpty ? nil : issuerCertificates,
            persistence: persistence
        )
    }

    /// The leaf `SecCertificate` backing this identity (for display / summary).
    public func leafCertificate() -> SecCertificate? {
        var certificate: SecCertificate?
        let status = SecIdentityCopyCertificate(secIdentity, &certificate)
        return status == errSecSuccess ? certificate : nil
    }

    /// Human-readable summary of the leaf certificate (subject CN, issuer CN,
    /// expiry) for the install/rotation UI. `nil` only if the leaf can't be
    /// read (should never happen for a valid import).
    public func summary() -> ClientCertificateSummary? {
        leafCertificate().map(CertificateInspector.summary(of:))
    }
}
