//! Upstream TLS configuration matching Go's `crypto/tls` defaults.
//!
//! The LS is a Go binary — its outbound TLS to Google uses Go's default
//! cipher suites, curves, and signature algorithms. This module configures
//! BoringSSL to produce a matching TLS ClientHello so Google sees the same
//! JA3/JA4 fingerprint regardless of whether our MITM is active.

use boring2::ssl::{SslConnector, SslMethod};
use tracing::debug;

/// Go's default cipher suites in the exact order Go's `crypto/tls` sends them.
///
/// TLS 1.3 ciphers (hardcoded in Go, not configurable):
///   TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256
///
/// TLS 1.2 ciphers (Go's default preference order):
///   ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-GCM-SHA256,
///   ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-GCM-SHA384,
///   ECDHE-ECDSA-CHACHA20-POLY1305, ECDHE-RSA-CHACHA20-POLY1305,
///   ECDHE-RSA-AES128-SHA, ECDHE-RSA-AES256-SHA,
///   AES128-GCM-SHA256, AES256-GCM-SHA384, AES128-SHA, AES256-SHA
const GO_CIPHER_LIST: &str = "\
TLS_AES_128_GCM_SHA256:\
TLS_AES_256_GCM_SHA384:\
TLS_CHACHA20_POLY1305_SHA256:\
ECDHE-ECDSA-AES128-GCM-SHA256:\
ECDHE-RSA-AES128-GCM-SHA256:\
ECDHE-ECDSA-AES256-GCM-SHA384:\
ECDHE-RSA-AES256-GCM-SHA384:\
ECDHE-ECDSA-CHACHA20-POLY1305:\
ECDHE-RSA-CHACHA20-POLY1305:\
ECDHE-RSA-AES128-SHA:\
ECDHE-RSA-AES256-SHA:\
AES128-GCM-SHA256:\
AES256-GCM-SHA384:\
AES128-SHA:\
AES256-SHA";

/// Go's default signature algorithms.
const GO_SIGALGS: &str = "\
ECDSA+SHA256:\
RSA-PSS+SHA256:\
RSA+SHA256:\
ECDSA+SHA384:\
RSA-PSS+SHA384:\
RSA+SHA384:\
RSA-PSS+SHA512:\
RSA+SHA512:\
RSA+SHA1";

/// Build an `SslConnector` that mimics Go's `crypto/tls` defaults.
///
/// If `alpn` is provided, sets ALPN protocols (e.g. `&[b"h2"]` for HTTP/2).
pub fn build_go_tls_connector(alpn: Option<&[&[u8]]>) -> SslConnector {
    let mut builder =
        SslConnector::builder(SslMethod::tls_client()).expect("SslConnector::builder");

    // Set Go's cipher list
    builder
        .set_cipher_list(GO_CIPHER_LIST)
        .expect("set_cipher_list");

    // Set Go's signature algorithms
    builder
        .set_sigalgs_list(GO_SIGALGS)
        .expect("set_sigalgs_list");

    // Set Go's default curves: X25519, P-256, P-384
    // BoringSSL uses set_curves_list with colon-separated names
    builder
        .set_curves_list("X25519:P-256:P-384")
        .expect("set_curves_list");

    // ALPN if requested (for HTTP/2)
    if let Some(protos) = alpn {
        let mut wire = Vec::new();
        for proto in protos {
            wire.push(proto.len() as u8);
            wire.extend_from_slice(proto);
        }
        builder.set_alpn_protos(&wire).expect("set_alpn_protos");
    }

    debug!("Built Go-matching TLS connector (BoringSSL)");
    builder.build()
}
