package cn.hztech.sdk;

import cn.hztech.sdk.crypto.sm4.SM4Util;
import cn.hztech.sdk.exception.CryptoException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

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

/**
 * SM4加密工具类测试
 */
class SM4UtilTest {

    private SM4Util sm4Util;

    @BeforeEach
    void setUp() {
        sm4Util = new SM4Util();
    }

    @Test
    void testGenerateKey() {
        String key = sm4Util.generateKey();
        assertNotNull(key);
        assertFalse(key.isEmpty());
    }

    @Test
    void testEncryptDecrypt() {
        String originalData = "这是一段测试数据，包含中文和English！";
        String key = sm4Util.generateKey();

        // 加密
        String encrypted = sm4Util.encrypt(originalData, key);
        assertNotNull(encrypted);
        assertNotEquals(originalData, encrypted);

        // 解密
        String decrypted = sm4Util.decrypt(encrypted, key);
        assertEquals(originalData, decrypted);
    }

    @Test
    void testEncryptWithDifferentKey() {
        String data = "测试数据";
        String key1 = sm4Util.generateKey();
        String key2 = sm4Util.generateKey();

        String encrypted1 = sm4Util.encrypt(data, key1);
        String encrypted2 = sm4Util.encrypt(data, key2);

        // 相同数据使用不同密钥加密，结果应该不同
        assertNotEquals(encrypted1, encrypted2);

        // 使用错误密钥解密应该失败
        assertThrows(Exception.class, () -> {
            sm4Util.decrypt(encrypted1, key2);
        });
    }

    @Test
    void testEncryptWithInvalidKey() {
        assertThrows(CryptoException.class, () -> {
            sm4Util.encrypt("data", "invalid_key");
        });
    }

    @Test
    void testDecryptWithInvalidKey() {
        assertThrows(CryptoException.class, () -> {
            sm4Util.decrypt("encrypted_data", "invalid_key");
        });
    }

    @Test
    void testEmptyData() {
        String key = sm4Util.generateKey();
        String encrypted = sm4Util.encrypt("", key);
        String decrypted = sm4Util.decrypt(encrypted, key);
        assertEquals("", decrypted);
    }

    @Test
    void testLargeData() {
        // 构造较大的数据
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 1000; i++) {
            sb.append("测试数据");
        }
        String largeData = sb.toString();

        String key = sm4Util.generateKey();
        String encrypted = sm4Util.encrypt(largeData, key);
        String decrypted = sm4Util.decrypt(encrypted, key);

        assertEquals(largeData, decrypted);
    }
}
