package com.ruoyi.framework.web.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.springframework.stereotype.Component;
import com.ruoyi.common.utils.StringUtils;

/**
 * CAS工具类
 * 
 * @author ruoyi
 */
@Component
public class CasUtils
{
    public String validateTicketByUrl(String validateUrl, String ticket, String service)
    {
        if (StringUtils.isEmpty(validateUrl) || StringUtils.isEmpty(ticket) || StringUtils.isEmpty(service))
        {
            return null;
        }
        try
        {
            String url = validateUrl
                    + (validateUrl.contains("?") ? "&" : "?")
                    + "ticket=" + URLEncoder.encode(ticket, StandardCharsets.UTF_8.toString())
                    + "&service=" + URLEncoder.encode(service, StandardCharsets.UTF_8.toString());
            String response = sendHttpRequest(url);
            return parseUsername(response);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 验证CAS票据
     * 
     * @param casServerUrl CAS服务器地址
     * @param ticket CAS票据
     * @param service 服务地址
     * @return 用户名，验证失败返回null
     */
    public String validateTicket(String casServerUrl, String ticket, String service)
    {
        if (StringUtils.isEmpty(casServerUrl) || StringUtils.isEmpty(ticket) || StringUtils.isEmpty(service))
        {
            return null;
        }

        try
        {
            // 构建验证URL
            String validateUrl = casServerUrl + "/serviceValidate"
                    + "?ticket=" + URLEncoder.encode(ticket, StandardCharsets.UTF_8.toString())
                    + "&service=" + URLEncoder.encode(service, StandardCharsets.UTF_8.toString());

            // 发送HTTP请求验证票据
            String response = sendHttpRequest(validateUrl);
            
            // 解析响应获取用户名
            return parseUsername(response);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 发送HTTP请求
     * 
     * @param urlString 请求URL
     * @return 响应内容
     * @throws IOException IO异常
     */
    private String sendHttpRequest(String urlString) throws IOException
    {
        URL url = new URL(urlString);
        HttpURLConnection connection = null;
        
        try
        {
            if (urlString.startsWith("https"))
            {
                // 配置HTTPS连接，忽略SSL证书验证
                HttpsURLConnection httpsConnection = (HttpsURLConnection) url.openConnection();
                httpsConnection.setSSLSocketFactory(createTrustAllSSLContext().getSocketFactory());
                httpsConnection.setHostnameVerifier((hostname, session) -> true);
                connection = httpsConnection;
            }
            else
            {
                connection = (HttpURLConnection) url.openConnection();
            }

            connection.setRequestMethod("GET");
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(10000);

            // 读取响应
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)))
            {
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null)
                {
                    response.append(line).append("\n");
                }
                return response.toString();
            }
        }
        finally
        {
            if (connection != null)
            {
                connection.disconnect();
            }
        }
    }

    /**
     * 创建信任所有证书的SSL上下文
     * 
     * @return SSL上下文
     */
    private SSLContext createTrustAllSSLContext()
    {
        try
        {
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, 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];
                    }
                }
            }, null);
            return sslContext;
        }
        catch (Exception e)
        {
            throw new RuntimeException("Failed to create SSL context", e);
        }
    }

    /**
     * 解析CAS响应获取用户名
     * 
     * @param response CAS服务器响应
     * @return 用户名，解析失败返回null
     */
    private String parseUsername(String response)
    {
        if (StringUtils.isEmpty(response))
        {
            return null;
        }

        // 检查是否验证成功
        if (!response.contains("<cas:authenticationSuccess>"))
        {
            return null;
        }

        // 提取用户名
        String userTag = "<cas:user>";
        String userEndTag = "</cas:user>";
        
        int startIndex = response.indexOf(userTag);
        if (startIndex == -1)
        {
            return null;
        }
        
        startIndex += userTag.length();
        int endIndex = response.indexOf(userEndTag, startIndex);
        if (endIndex == -1)
        {
            return null;
        }
        
        return response.substring(startIndex, endIndex).trim();
    }
}
