import Foundation
import Security
import Testing
@testable import ClientTLS

// C-iOS-1 · PKCS#12 import against a real OpenSSL-generated fixture `.p12`,
// including the wrong-passphrase and corrupt-file error mappings.

@Test("import with the correct passphrase yields an identity whose leaf CN matches")
func importSucceedsAndExposesLeaf() throws {
    // Arrange
    let data = ClientTLSFixtures.deviceP12Data

    // Act
    let identity = try PKCS12Importer.importIdentity(
        data: data, passphrase: ClientTLSFixtures.passphrase
    )

    // Assert
    let summary = try #require(identity.summary())
    #expect(summary.subjectCommonName == ClientTLSFixtures.leafCommonName)
    #expect(summary.issuerCommonName == ClientTLSFixtures.issuerCommonName)
    // 825-day leaf minted at authoring time → not yet expired.
    #expect(summary.isExpired() == false)
}

@Test("import drops the leaf from the issuer chain (credential must not repeat it)")
func importIssuerChainExcludesLeaf() throws {
    // Arrange / Act
    let identity = try PKCS12Importer.importIdentity(
        data: ClientTLSFixtures.deviceP12Data, passphrase: ClientTLSFixtures.passphrase
    )

    // Assert — fixture chain is [leaf, CA]; issuerCertificates keeps only the CA.
    let leaf = try #require(identity.leafCertificate())
    let leafData = SecCertificateCopyData(leaf) as Data
    #expect(identity.issuerCertificates.count == 1)
    for issuer in identity.issuerCertificates {
        #expect((SecCertificateCopyData(issuer) as Data) != leafData)
    }
}

@Test("wrong passphrase maps errSecAuthFailed → .wrongPassphrase")
func importWrongPassphrase() {
    // Arrange / Act / Assert
    #expect(throws: PKCS12ImportError.wrongPassphrase) {
        _ = try PKCS12Importer.importIdentity(
            data: ClientTLSFixtures.deviceP12Data, passphrase: "not-the-passphrase"
        )
    }
}

@Test("garbage bytes map errSecDecode → .corruptFile")
func importCorruptFile() {
    // Arrange
    let garbage = Data([0x00, 0x01, 0x02, 0x03, 0x99, 0xAB, 0xCD, 0xEF])

    // Act / Assert
    #expect(throws: PKCS12ImportError.corruptFile) {
        _ = try PKCS12Importer.importIdentity(data: garbage, passphrase: "x")
    }
}

@Test("empty data is treated as a corrupt file, not a crash")
func importEmptyData() {
    #expect(throws: PKCS12ImportError.corruptFile) {
        _ = try PKCS12Importer.importIdentity(data: Data(), passphrase: "x")
    }
}
