package cn.hztech.sdk;

import cn.hztech.sdk.client.SdkHttpClient;
import cn.hztech.sdk.config.SdkProperties;
import cn.hztech.sdk.crypto.envelope.GmPacket;
import cn.hztech.sdk.crypto.envelope.GmPacketBuilder;
import cn.hztech.sdk.crypto.envelope.GmPacketParser;
import cn.hztech.sdk.crypto.sm2.SM2Util;
import cn.hztech.sdk.crypto.sm4.SM4Util;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.security.*;
import java.util.Base64;

import static org.junit.jupiter.api.Assertions.*;

/**
 * SDK HTTP客户端集成测试
 */
class SdkHttpClientIntegrationTest {

    private MockWebServer mockWebServer;
    private SdkHttpClient httpClient;
    private SM2Util sm2Util;
    private SM4Util sm4Util;
    private KeyPair senderKeyPair;
    private KeyPair receiverKeyPair;

    @BeforeEach
    void setUp() throws Exception {
        mockWebServer = new MockWebServer();
        mockWebServer.start();

        sm2Util = new SM2Util();
        sm4Util = new SM4Util();

        // 生成密钥对
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC", "BC");
        keyGen.initialize(256);
        senderKeyPair = keyGen.generateKeyPair();
        receiverKeyPair = keyGen.generateKeyPair();

        // 创建HTTP客户端
        String gatewayUrl = mockWebServer.url("").toString();
        gatewayUrl = gatewayUrl.substring(0, gatewayUrl.length() - 1); // 移除末尾的/

        String senderPrivateKey = Base64.getEncoder().encodeToString(senderKeyPair.getPrivate().getEncoded());
        String receiverPublicKey = Base64.getEncoder().encodeToString(receiverKeyPair.getPublic().getEncoded());

        GmPacketBuilder packetBuilder = new GmPacketBuilder("TEST_APP", senderPrivateKey, receiverPublicKey, sm2Util, sm4Util);
        GmPacketParser packetParser = new GmPacketParser(senderPrivateKey, receiverPublicKey, sm2Util, sm4Util, 60000L);

        httpClient = new SdkHttpClient(gatewayUrl, 10000, 30000, 30000, packetBuilder, packetParser, false, false, 0, 0);
    }

    @AfterEach
    void tearDown() throws IOException {
        mockWebServer.shutdown();
    }

    @Test
    void testSuccessfulRequest() throws Exception {
        // 准备响应数据
        String responseData = "{\"code\":200,\"message\":\"success\",\"data\":{\"id\":\"123\",\"name\":\"测试\"}}";

        // 模拟服务器响应
        mockWebServer.enqueue(new MockResponse()
            .setBody(responseData)
            .setResponseCode(200)
            .addHeader("Content-Type", "application/json"));

        // 执行请求（这里会失败因为MockWebServer不处理加密）
        // 实际使用中需要真实的加密响应
        assertThrows(Exception.class, () -> {
            httpClient.post("/test/api", "{\"test\":\"data\"}", String.class);
        });
    }

    @Test
    void testEncryptionDecryptionFlow() {
        // 测试加密解密流程
        String appId = "TEST_APP";
        String businessData = "{\"userId\":\"123\",\"userName\":\"测试\"}";

        String senderPrivateKey = Base64.getEncoder().encodeToString(senderKeyPair.getPrivate().getEncoded());
        String receiverPublicKey = Base64.getEncoder().encodeToString(receiverKeyPair.getPublic().getEncoded());

        // 构建报文
        GmPacketBuilder builder = new GmPacketBuilder(appId, senderPrivateKey, receiverPublicKey, sm2Util, sm4Util);
        GmPacket packet = builder.build(businessData);

        assertNotNull(packet);
        assertEquals(appId, packet.getAppId());

        // 解析报文
        String receiverPrivateKey = Base64.getEncoder().encodeToString(receiverKeyPair.getPrivate().getEncoded());
        String senderPublicKey = Base64.getEncoder().encodeToString(senderKeyPair.getPublic().getEncoded());

        GmPacketParser parser = new GmPacketParser(receiverPrivateKey, senderPublicKey, sm2Util, sm4Util, 60000L);
        String decrypted = parser.parse(packet);

        assertEquals(businessData, decrypted);
    }
}
