package transport

import (
	"crypto/sha256"
	"crypto/x509"
	"encoding/hex"
	"log/slog"
)

// LogHandshakeOK emits a structured slog record for a successful mTLS
// handshake. Per REQ-038, the fields are: event=mtls.handshake,
// result=ok, peer, cert_fp.
func LogHandshakeOK(log *slog.Logger, peer, certFP string) {
	if log == nil {
		return
	}
	log.Info("mtls.handshake",
		slog.String("event", "mtls.handshake"),
		slog.String("result", "ok"),
		slog.String("peer", peer),
		slog.String("cert_fp", certFP),
	)
}

// LogHandshakeFailed emits a structured slog record for a failed mTLS
// handshake. Per REQ-038, the fields are: event=mtls.handshake,
// result=failed, peer, cert_fp (may be empty if no cert was presented
// before the failure), err. The log level is WARN — handshake failures
// are operationally interesting but not always fatal (e.g., a scanner
// probing the port).
func LogHandshakeFailed(log *slog.Logger, peer, certFP string, err error) {
	if log == nil {
		return
	}
	attrs := []any{
		slog.String("event", "mtls.handshake"),
		slog.String("result", "failed"),
		slog.String("peer", peer),
		slog.String("cert_fp", certFP),
	}
	if err != nil {
		attrs = append(attrs, slog.String("err", err.Error()))
	}
	log.Warn("mtls.handshake", attrs...)
}

// LogHandshakeFromCert is a convenience wrapper that pulls the fingerprint
// off a parsed *x509.Certificate and calls LogHandshakeOK.
func LogHandshakeFromCert(log *slog.Logger, peer string, cert *x509.Certificate) {
	if cert == nil {
		LogHandshakeOK(log, peer, "")
		return
	}
	LogHandshakeOK(log, peer, FingerprintOfCert(cert))
}

// FingerprintOfCert is a thin wrapper that returns the SHA-256 hex of a
// cert's DER bytes. Re-exported here so transport callers don't need
// to import the security package directly.
func FingerprintOfCert(cert *x509.Certificate) string {
	if cert == nil {
		return ""
	}
	sum := sha256.Sum256(cert.Raw)
	return hex.EncodeToString(sum[:])
}
