package com.microservices.common.httpClient.config;

import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.ssl.SSLContexts;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

/**
 * SSL/TLS 配置工厂类
 * 用于创建支持 HTTPS 的 SSLContext 和 SocketFactory
 *
 * @author otto
 */
public class SSLContextFactory {

    private static final Logger logger = LoggerFactory.getLogger(SSLContextFactory.class);

    /**
     * 创建支持所有 TLS 版本的 SSLContext
     * 信任所有证书（仅用于内部系统调用）
     *
     * @return SSLContext 实例
     */
    public static SSLContext createSSLContext() {
        try {
            // 使用 TLSv1.2 或更高版本
            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");

            // 创建信任所有证书的 TrustManager
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public void checkServerTrusted(X509Certificate[] chain, String authType) {
                        }

                        @Override
                        public X509Certificate[] getAcceptedIssuers() {
                            return new X509Certificate[0];
                        }
                    }
            };

            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            logger.debug("SSLContext 创建成功，使用 TLSv1.2 协议");
            return sslContext;
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            logger.error("创建 SSLContext 失败", e);
            throw new RuntimeException("创建 SSLContext 失败", e);
        }
    }

    /**
     * 创建 SSLConnectionSocketFactory
     * 跳过主机名验证（仅用于内部系统调用）
     *
     * @return SSLConnectionSocketFactory 实例
     */
    public static SSLConnectionSocketFactory createSSLConnectionSocketFactory() {
        try {
            SSLContext sslContext = createSSLContext();

            // 创建跳过主机名验证的 HostnameVerifier
            HostnameVerifier allowAllHosts = new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    // 记录连接的主机信息，便于调试
                    logger.debug("SSL 连接主机: {}, 证书主体: {}", hostname, getCertificateSubject(session));
                    return true;
                }

                private String getCertificateSubject(SSLSession session) {
                    try {
                        return session.getPeerPrincipal().toString();
                    } catch (Exception e) {
                        return "Unknown";
                    }
                }
            };

            // 支持的协议：TLSv1.2, TLSv1.3
            String[] supportedProtocols = new String[]{"TLSv1.2", "TLSv1.3"};

            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
                    sslContext,
                    supportedProtocols,
                    null,  // 使用默认的密码套件
                    allowAllHosts
            );

            logger.debug("SSLConnectionSocketFactory 创建成功，支持的协议: TLSv1.2, TLSv1.3");
            return sslSocketFactory;
        } catch (Exception e) {
            logger.error("创建 SSLConnectionSocketFactory 失败", e);
            throw new RuntimeException("创建 SSLConnectionSocketFactory 失败", e);
        }
    }

    /**
     * 创建用于信任所有证书的 TrustManager（用于日志记录）
     *
     * @return TrustManager 数组
     */
    public static TrustManager[] createTrustAllManagers() {
        return new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
                        logger.debug("客户端证书验证通过");
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
                        if (chain != null && chain.length > 0) {
                            X509Certificate cert = chain[0];
                            logger.debug("服务器证书验证通过 - 主体: {}, 颁发者: {}, 有效期: {} - {}",
                                    cert.getSubjectDN(),
                                    cert.getIssuerDN(),
                                    cert.getNotBefore(),
                                    cert.getNotAfter());
                        }
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                }
        };
    }
}
