package tech.easyflow.datacenter.meta.entity;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Test;
import tech.easyflow.datacenter.entity.DatacenterTable;
import tech.easyflow.datacenter.meta.model.DatacenterCatalogMeta;

import java.math.BigInteger;

/**
 * 数据中枢雪花 ID 的 HTTP JSON 序列化测试。
 */
public class DatacenterIdJsonSerializationTest {

    private static final BigInteger UNSAFE_JAVASCRIPT_INTEGER = new BigInteger("9007199254740993");
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 验证连接、目录和表的雪花 ID 会输出为字符串，避免 JavaScript 精度丢失。
     *
     * @throws Exception JSON 序列化失败时抛出
     */
    @Test
    public void shouldSerializeDatacenterSnowflakeIdsAsStrings() throws Exception {
        DatacenterSource source = new DatacenterSource();
        source.setId(UNSAFE_JAVASCRIPT_INTEGER);
        assertTextualId(source, "id");

        DatacenterCatalog catalog = new DatacenterCatalog();
        catalog.setId(UNSAFE_JAVASCRIPT_INTEGER);
        assertTextualId(catalog, "id");

        DatacenterCatalogMeta catalogMeta = new DatacenterCatalogMeta();
        catalogMeta.setId(UNSAFE_JAVASCRIPT_INTEGER);
        catalogMeta.setSourceId(UNSAFE_JAVASCRIPT_INTEGER);
        assertTextualId(catalogMeta, "id");
        assertTextualId(catalogMeta, "sourceId");

        DatacenterTable table = new DatacenterTable();
        table.setId(UNSAFE_JAVASCRIPT_INTEGER);
        table.setSourceId(UNSAFE_JAVASCRIPT_INTEGER);
        table.setCatalogId(UNSAFE_JAVASCRIPT_INTEGER);
        assertTextualId(table, "id");
        assertTextualId(table, "sourceId");
        assertTextualId(table, "catalogId");
    }

    /**
     * 验证给定属性被输出为精确的文本 ID。
     *
     * @param value 待序列化对象
     * @param fieldName ID 属性名
     * @throws Exception JSON 序列化失败时抛出
     */
    private void assertTextualId(Object value, String fieldName) throws Exception {
        JsonNode node = objectMapper.readTree(objectMapper.writeValueAsString(value)).path(fieldName);
        Assert.assertTrue(fieldName + " 应为 JSON 字符串", node.isTextual());
        Assert.assertEquals(UNSAFE_JAVASCRIPT_INTEGER.toString(), node.asText());
    }
}
