package com.ycwl.basic.puzzle.fill.datasource;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.nio.file.Files;
import java.nio.file.Path;

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

/**
 * 静态值数据源策略测试
 */
@DisplayName("静态值数据源策略测试")
class StaticValueDataSourceStrategyTest {

    private StaticValueDataSourceStrategy strategy;
    private ObjectMapper objectMapper;

    @BeforeEach
    void setUp() {
        strategy = new StaticValueDataSourceStrategy();
        objectMapper = new ObjectMapper();
    }

    @Test
    @DisplayName("应该返回正确的支持类型")
    void shouldReturnCorrectSupportedType() {
        assertEquals("STATIC_VALUE", strategy.getSupportedType());
    }

    @Test
    @DisplayName("应该返回sourceFilter中的value值")
    void shouldReturnValueFromSourceFilter() throws Exception {
        // Given
        String expectedValue = "https://oss.example.com/static/default.jpg";
        JsonNode sourceFilter = objectMapper.readTree("{\"value\": \"" + expectedValue + "\"}");

        DataSourceContext context = DataSourceContext.builder().build();

        // When
        String result = strategy.resolve(sourceFilter, null, context);

        // Then
        assertEquals(expectedValue, result);
    }

    @Test
    @DisplayName("当sourceFilter为null时应该返回null")
    void shouldReturnNullWhenSourceFilterIsNull() {
        // Given
        DataSourceContext context = DataSourceContext.builder().build();

        // When
        String result = strategy.resolve(null, null, context);

        // Then
        assertNull(result);
    }

    @Test
    @DisplayName("当sourceFilter缺少value字段时应该返回null")
    void shouldReturnNullWhenValueFieldIsMissing() throws Exception {
        // Given
        JsonNode sourceFilter = objectMapper.readTree("{\"otherField\": \"test\"}");

        DataSourceContext context = DataSourceContext.builder().build();

        // When
        String result = strategy.resolve(sourceFilter, null, context);

        // Then
        assertNull(result);
    }

    @Test
    @DisplayName("sortStrategy参数应该被忽略")
    void shouldIgnoreSortStrategy() throws Exception {
        // Given
        String expectedValue = "static_value";
        JsonNode sourceFilter = objectMapper.readTree("{\"value\": \"" + expectedValue + "\"}");

        DataSourceContext context = DataSourceContext.builder().build();

        // When
        String result = strategy.resolve(sourceFilter, "LATEST", context);

        // Then
        assertEquals(expectedValue, result);
    }

    @Test
    @DisplayName("应该支持各种类型的字符串值")
    void shouldSupportVariousStringValues() throws Exception {
        // 测试URL
        testStaticValue("https://example.com/image.jpg");

        // 测试普通文本
        testStaticValue("Hello World");

        // 测试空字符串
        testStaticValue("");

        // 测试包含特殊字符的文本
        testStaticValue("测试中文/Special!@#$%");
    }

    @Test
    @DisplayName("应该支持localPath字段并返回绝对路径")
    void shouldSupportLocalPathField() throws Exception {
        Path temp = Files.createTempFile("puzzle-static", ".png");
        Files.writeString(temp, "test");

        try {
            JsonNode sourceFilter = objectMapper.readTree("{\"localPath\":\"" + temp.toString().replace("\\", "\\\\") + "\"}");
            DataSourceContext context = DataSourceContext.builder().build();
            String result = strategy.resolve(sourceFilter, null, context);
            assertEquals(temp.toAbsolutePath().toString(), result);
        } finally {
            Files.deleteIfExists(temp);
        }
    }

    @Test
    @DisplayName("当localPath无效时应该返回null")
    void shouldReturnNullWhenLocalPathInvalid() throws Exception {
        JsonNode sourceFilter = objectMapper.readTree("{\"localPath\":\"/path/not/found.png\"}");
        DataSourceContext context = DataSourceContext.builder().build();

        String result = strategy.resolve(sourceFilter, null, context);
        assertNull(result);
    }

    private void testStaticValue(String value) throws Exception {
        JsonNode sourceFilter = objectMapper.readTree("{\"value\": \"" + value + "\"}");
        DataSourceContext context = DataSourceContext.builder().build();
        String result = strategy.resolve(sourceFilter, null, context);
        assertEquals(value, result);
    }
}
